summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-23 23:24:23 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-23 23:24:23 +0800
commit3f815c836beb054a13f8d250f6f05a54778b72ba (patch)
tree04e39933feecbc34cd8ef36c86f838ea8181c635 /script
parenta7afda10d2ea044a8ea3c83d4656736a6969a101 (diff)
downloadlua-language-server-3f815c836beb054a13f8d250f6f05a54778b72ba.zip
new diagnostic: `need-check-nil`
Diffstat (limited to 'script')
-rw-r--r--script/core/diagnostics/need-check-nil.lua39
-rw-r--r--script/proto/define.lua16
-rw-r--r--script/vm/compiler.lua3
-rw-r--r--script/vm/node.lua2
-rw-r--r--script/vm/sign.lua2
5 files changed, 51 insertions, 11 deletions
diff --git a/script/core/diagnostics/need-check-nil.lua b/script/core/diagnostics/need-check-nil.lua
new file mode 100644
index 00000000..8654a7a6
--- /dev/null
+++ b/script/core/diagnostics/need-check-nil.lua
@@ -0,0 +1,39 @@
+local files = require 'files'
+local guide = require 'parser.guide'
+local vm = require 'vm'
+local lang = require 'language'
+
+return function (uri, callback)
+ local state = files.getState(uri)
+ if not state then
+ return
+ end
+
+ guide.eachSourceType(state.ast, 'getlocal', function (src)
+ local checkNil
+ local nxt = src.next
+ if nxt then
+ if nxt.type == 'getfield'
+ or nxt.type == 'getmethod'
+ or nxt.type == 'getindex'
+ or nxt.type == 'call' then
+ checkNil = true
+ end
+ end
+ local call = src.parent
+ if call and call.type == 'call' and call.node == src then
+ checkNil = true
+ end
+ if not checkNil then
+ return
+ end
+ local node = vm.compileNode(src)
+ if node:hasFalsy() then
+ callback {
+ start = src.start,
+ finish = src.finish,
+ message = lang.script('DIAG_MISS_NEED_CHECK_NIL'),
+ }
+ end
+ end)
+end
diff --git a/script/proto/define.lua b/script/proto/define.lua
index 9da67039..fb60c56c 100644
--- a/script/proto/define.lua
+++ b/script/proto/define.lua
@@ -9,10 +9,10 @@ m.DiagnosticSeverity = {
}
---@alias DiagnosticDefaultSeverity
----| '"Hint"'
----| '"Information"'
----| '"Warning"'
----| '"Error"'
+---| 'Hint'
+---| 'Information'
+---| 'Warning'
+---| 'Error'
--- 诊断类型与默认等级
---@type table<string, DiagnosticDefaultSeverity>
@@ -48,6 +48,7 @@ m.DiagnosticDefaultSeverity = {
['await-in-sync'] = 'Warning',
['not-yieldable'] = 'Warning',
['discard-returns'] = 'Warning',
+ ['need-check-nil'] = 'Warning',
['type-check'] = 'Warning',
['duplicate-doc-alias'] = 'Warning',
@@ -64,9 +65,9 @@ m.DiagnosticDefaultSeverity = {
}
---@alias DiagnosticDefaultNeededFileStatus
----| '"Any"'
----| '"Opened"'
----| '"None"'
+---| 'Any'
+---| 'Opened'
+---| 'None'
-- 文件状态
m.FileStatus = {
@@ -108,6 +109,7 @@ m.DiagnosticDefaultNeededFileStatus = {
['await-in-sync'] = 'None',
['not-yieldable'] = 'None',
['discard-returns'] = 'Opened',
+ ['need-check-nil'] = 'Opened',
['type-check'] = 'None',
['duplicate-doc-alias'] = 'Any',
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 4917d33a..1f33a784 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -1435,9 +1435,8 @@ local compilerSwitch = util.switch()
elseif r1 == false then
vm.setNode(source, node1)
else
- vm.getNode(source):merge(node1)
- vm.getNode(source):setTruly()
vm.getNode(source):merge(node2)
+ vm.getNode(source):addOptional()
end
end
if source.op.type == 'or' then
diff --git a/script/vm/node.lua b/script/vm/node.lua
index d52c2a84..06023ca5 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -80,7 +80,7 @@ function mt:isOptional()
end
---@return boolean
-function mt:isFalsy()
+function mt:hasFalsy()
if self.optional then
return true
end
diff --git a/script/vm/sign.lua b/script/vm/sign.lua
index 78d61022..795916fa 100644
--- a/script/vm/sign.lua
+++ b/script/vm/sign.lua
@@ -128,7 +128,7 @@ function mt:resolve(uri, args, removeGeneric)
local function buildArgNode(argNode, knownTypes)
local newArgNode = vm.createNode()
for n in argNode:eachObject() do
- if argNode:isFalsy() then
+ if argNode:hasFalsy() then
goto CONTINUE
end
local view = infer.viewObject(n)