diff options
-rw-r--r-- | server/src/core/diagnostics.lua | 37 | ||||
-rw-r--r-- | server/src/parser/ast.lua | 5 | ||||
-rw-r--r-- | server/src/vm/value.lua | 2 | ||||
-rw-r--r-- | server/test/definition/emmy.lua | 2 | ||||
-rw-r--r-- | server/test/diagnostics/init.lua | 11 |
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 +]] |