summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/core/diagnostics.lua37
-rw-r--r--server/src/parser/ast.lua5
-rw-r--r--server/src/vm/value.lua2
-rw-r--r--server/test/definition/emmy.lua2
-rw-r--r--server/test/diagnostics/init.lua11
5 files changed, 54 insertions, 3 deletions
diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua
index f9d6f818..828ee1fe 100644
--- a/server/src/core/diagnostics.lua
+++ b/server/src/core/diagnostics.lua
@@ -556,6 +556,41 @@ function mt:checkEmmyParam(source, callback, mark)
end
end
+function mt:checkEmmyField(source, callback, mark)
+ ---@type EmmyClass
+ local class = source:get 'target class'
+ -- 必须写在 class 的后面
+ if not class then
+ callback(source.start, source.finish, lang.script.DIAG_NEED_CLASS)
+ end
+
+ -- 检查重复的 field
+ if class and not mark[class] then
+ mark[class] = true
+ local lists = {}
+ class:eachField(function (field)
+ local name = field:getName()
+ if not lists[name] then
+ lists[name] = {}
+ end
+ lists[name][#lists[name]+1] = field:getSource()[2]
+ end)
+ for _, list in pairs(lists) do
+ if #list > 1 then
+ local related = {}
+ for _, src in ipairs(list) do
+ related[#related+1] = {
+ src.start,
+ src.finish,
+ src.uri,
+ }
+ callback(src.start, src.finish, lang.script.DIAG_DUPLICATE_FIELD)
+ end
+ end
+ end
+ end
+end
+
function mt:searchEmmyLua(callback)
local mark = {}
self.vm:eachSource(function (source)
@@ -567,6 +602,8 @@ function mt:searchEmmyLua(callback)
self:checkEmmyAlias(source, callback)
elseif source.type == 'emmyParam' then
self:checkEmmyParam(source, callback, mark)
+ elseif source.type == 'emmyField' then
+ self:checkEmmyField(source, callback, mark)
end
end)
end
diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua
index f93870e4..72c441ca 100644
--- a/server/src/parser/ast.lua
+++ b/server/src/parser/ast.lua
@@ -1206,11 +1206,14 @@ local Defs = {
}
end,
EmmyField = function (access, fieldName, ...)
- return {
+ local obj = {
type = 'emmyField',
access, fieldName,
...
}
+ obj.start = obj[2].start
+ obj.finish = obj[3].finish
+ return obj
end,
EmmyGenericBlock = function (genericName, parentName)
return { genericName, parentName }
diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua
index e924f642..43f278c0 100644
--- a/server/src/vm/value.lua
+++ b/server/src/vm/value.lua
@@ -549,7 +549,7 @@ function mt:setEmmy(emmy)
emmyClass:eachField(function (field)
local name = field:getName()
local value = field:bindValue()
- self:setChild(name, value, field:getSource()[2])
+ self:setChild(name, value, field:getSource())
end)
elseif emmy.type == 'emmy.type' then
---@type EmmyType
diff --git a/server/test/definition/emmy.lua b/server/test/definition/emmy.lua
index 937f1d70..ef7c1773 100644
--- a/server/test/definition/emmy.lua
+++ b/server/test/definition/emmy.lua
@@ -74,7 +74,7 @@ TEST [[
TEST [[
---@class Class
----@field <!name!> string
+---@field <!name string!>
---@field id integer
local mt = {}
mt.<?name?>
diff --git a/server/test/diagnostics/init.lua b/server/test/diagnostics/init.lua
index 60c029bb..499ffe78 100644
--- a/server/test/diagnostics/init.lua
+++ b/server/test/diagnostics/init.lua
@@ -415,3 +415,14 @@ local function f(x, y)
end
f()
]]
+
+TEST [[
+---@field <!x Class!>
+---@class Class
+]]
+
+TEST [[
+---@class Class
+---@field <!x!> Class
+---@field <!x!> Class
+]]