summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/diagnostics/duplicate-set-field.lua111
-rw-r--r--script/lclient.lua2
-rw-r--r--script/proto/diagnostic.lua9
-rw-r--r--test.lua1
-rw-r--r--test/command/auto-require.lua1
-rw-r--r--test/crossfile/diagnostic.lua35
-rw-r--r--test/diagnostics/common.lua4
7 files changed, 84 insertions, 79 deletions
diff --git a/script/core/diagnostics/duplicate-set-field.lua b/script/core/diagnostics/duplicate-set-field.lua
index ce67ab46..9d6f10ce 100644
--- a/script/core/diagnostics/duplicate-set-field.lua
+++ b/script/core/diagnostics/duplicate-set-field.lua
@@ -5,96 +5,55 @@ local guide = require 'parser.guide'
local vm = require 'vm'
local await = require 'await'
+local sourceTypes = {
+ 'setfield',
+ 'setmethod',
+ 'setindex',
+}
+
---@async
return function (uri, callback)
- local ast = files.getState(uri)
- if not ast then
+ local state = files.getState(uri)
+ if not state then
return
end
---@async
- guide.eachSourceType(ast.ast, 'local', function (source)
- if not source.ref then
+ guide.eachSourceTypes(state.ast, sourceTypes, function (src)
+ await.delay()
+ local name = guide.getKeyName(src)
+ if not name then
return
end
- await.delay()
- local sets = {}
- for _, ref in ipairs(source.ref) do
- if ref.type ~= 'getlocal' then
+ local value = vm.getObjectValue(src)
+ if not value or value.type ~= 'function' then
+ return
+ end
+ local defs = vm.getDefs(src)
+ for _, def in ipairs(defs) do
+ if def == src then
goto CONTINUE
end
- local nxt = ref.next
- if not nxt then
+ if def.type ~= 'setfield'
+ and def.type ~= 'setmethod'
+ and def.type ~= 'setindex' then
goto CONTINUE
end
- if nxt.type == 'setfield'
- or nxt.type == 'setmethod'
- or nxt.type == 'setindex' then
- local name = guide.getKeyName(nxt)
- if not name then
- goto CONTINUE
- end
- local value = vm.getObjectValue(nxt)
- if not value or value.type ~= 'function' then
- goto CONTINUE
- end
- if not sets[name] then
- sets[name] = {}
- end
- sets[name][#sets[name]+1] = nxt
+ local defValue = vm.getObjectValue(def)
+ if not defValue or defValue.type ~= 'function' then
+ goto CONTINUE
end
+ callback {
+ start = src.start,
+ finish = src.finish,
+ related = {{
+ start = def.start,
+ finish = def.finish,
+ uri = guide.getUri(def),
+ }},
+ message = lang.script('DIAG_DUPLICATE_SET_FIELD', name),
+ }
::CONTINUE::
end
- for name, values in pairs(sets) do
- if #values <= 1 then
- goto CONTINUE_SETS
- end
- local blocks = {}
- for _, value in ipairs(values) do
- local block = guide.getBlock(value)
- if block then
- if not blocks[block] then
- blocks[block] = {}
- end
- blocks[block][#blocks[block]+1] = value
- end
- end
- for _, defs in pairs(blocks) do
- if #defs <= 1 then
- goto CONTINUE_BLOCKS
- end
- local related = {}
- for i = 1, #defs do
- local def = defs[i]
- related[i] = {
- start = def.start,
- finish = def.finish,
- uri = uri,
- }
- end
- for i = 1, #defs - 1 do
- local def = defs[i]
- callback {
- start = def.start,
- finish = def.finish,
- related = related,
- message = lang.script('DIAG_DUPLICATE_SET_FIELD', name),
- level = define.DiagnosticSeverity.Hint,
- tags = { define.DiagnosticTag.Unnecessary },
- }
- end
- for i = #defs, #defs do
- local def = defs[i]
- callback {
- start = def.start,
- finish = def.finish,
- related = related,
- message = lang.script('DIAG_DUPLICATE_SET_FIELD', name),
- }
- end
- ::CONTINUE_BLOCKS::
- end
- ::CONTINUE_SETS::
- end
end)
end
diff --git a/script/lclient.lua b/script/lclient.lua
index e1504e61..13b431b0 100644
--- a/script/lclient.lua
+++ b/script/lclient.lua
@@ -24,6 +24,7 @@ function mt:__close()
end
function mt:_fakeProto()
+ ---@diagnostic disable-next-line: duplicate-set-field
proto.send = function (data)
self._outs[#self._outs+1] = data
if self.onSend then
@@ -47,6 +48,7 @@ function mt:_localLoadFile()
---@async
---@param name string
---@param params any
+ ---@diagnostic disable-next-line: duplicate-set-field
pub.awaitTask = function (name, params)
if name == 'loadFile' then
local path = params
diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua
index be30bcec..ceb42f8b 100644
--- a/script/proto/diagnostic.lua
+++ b/script/proto/diagnostic.lua
@@ -173,7 +173,6 @@ m.register {
m.register {
'duplicate-index',
- 'duplicate-set-field',
} {
group = 'duplicate',
severity = 'Warning',
@@ -181,6 +180,14 @@ m.register {
}
m.register {
+ 'duplicate-set-field',
+} {
+ group = 'duplicate',
+ severity = 'Warning',
+ status = 'Opened',
+}
+
+m.register {
'close-non-object',
'deprecated',
'discard-returns',
diff --git a/test.lua b/test.lua
index 3f6eb73c..329de053 100644
--- a/test.lua
+++ b/test.lua
@@ -13,6 +13,7 @@ METAPATH = METAPATH or (ROOT:string() .. '/meta')
collectgarbage 'generational'
+---@diagnostic disable-next-line: duplicate-set-field
io.write = function () end
---@diagnostic disable-next-line: lowercase-global
diff --git a/test/command/auto-require.lua b/test/command/auto-require.lua
index c55fd334..8c6a8971 100644
--- a/test/command/auto-require.lua
+++ b/test/command/auto-require.lua
@@ -12,6 +12,7 @@ assert(applyAutoRequire)
local originEditText = client.editText
local EditResult
+---@diagnostic disable-next-line: duplicate-set-field
client.editText = function (uri, edits)
EditResult = edits[1]
end
diff --git a/test/crossfile/diagnostic.lua b/test/crossfile/diagnostic.lua
index 58c89805..126a2ab8 100644
--- a/test/crossfile/diagnostic.lua
+++ b/test/crossfile/diagnostic.lua
@@ -8,6 +8,7 @@ local catch = require 'catch'
config.get(nil, 'Lua.diagnostics.neededFileStatus')['deprecated'] = 'Any'
config.get(nil, 'Lua.diagnostics.neededFileStatus')['type-check'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['duplicate-set-field'] = 'Any'
config.get(nil, 'Lua.diagnostics.neededFileStatus')['codestyle-check'] = 'None'
rawset(_G, 'TEST', true)
@@ -176,3 +177,37 @@ TEST {
---@field <!x!> number
]]}
}
+
+TEST {
+ { path = 'a.lua', content = [[
+ ---@class A
+ local mt
+
+ function <!mt:init!>()
+ end
+ ]]},
+ { path = 'b.lua', content = [[
+ ---@class A
+ local mt
+
+ function <!mt:init!>()
+ end
+ ]]}
+}
+
+TEST {
+ { path = 'a.lua', content = [[
+ ---@class A
+ local mt
+
+ function mt:init()
+ end
+ ]]},
+ { path = 'b.lua', content = [[
+ ---@class B: A
+ local mt
+
+ function mt:init()
+ end
+ ]]}
+}
diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua
index 5e0b3d2a..b91380b8 100644
--- a/test/diagnostics/common.lua
+++ b/test/diagnostics/common.lua
@@ -1119,11 +1119,11 @@ return m
TEST [[
local m = {}
-function m:fff()
+function <!m:fff!>()
end
do
- function m:fff()
+ function <!m:fff!>()
end
end