diff options
-rw-r--r-- | script/core/completion/completion.lua | 34 | ||||
-rw-r--r-- | script/vm/global.lua | 23 | ||||
-rw-r--r-- | script/vm/type.lua | 44 | ||||
-rw-r--r-- | test/completion/common.lua | 34 |
4 files changed, 88 insertions, 47 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 39b54209..f87b55a6 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1181,11 +1181,25 @@ local function insertDocEnum(state, pos, doc, enums) if not key then goto CONTINUE end - if field.value.type == 'integer' - or field.value.type == 'string' then - if parentName then - enums[#enums+1] = { - label = parentName .. '.' .. key, + if parentName then + enums[#enums+1] = { + label = parentName .. '.' .. key, + kind = define.CompletionItemKind.EnumMember, + id = stack(field, function (newField) ---@async + return { + detail = buildDetail(newField), + description = buildDesc(newField), + } + end), + } + end + for nd in vm.compileNode(field.value):eachObject() do + if nd.type == 'boolean' + or nd.type == 'number' + or nd.type == 'integer' + or nd.type == 'string' then + valueEnums[#valueEnums+1] = { + label = util.viewLiteral(nd[1]), kind = define.CompletionItemKind.EnumMember, id = stack(field, function (newField) ---@async return { @@ -1195,16 +1209,6 @@ local function insertDocEnum(state, pos, doc, enums) end), } end - valueEnums[#valueEnums+1] = { - label = util.viewLiteral(field.value[1]), - kind = define.CompletionItemKind.EnumMember, - id = stack(field, function (newField) ---@async - return { - detail = buildDetail(newField), - description = buildDesc(newField), - } - end), - } end ::CONTINUE:: end diff --git a/script/vm/global.lua b/script/vm/global.lua index 027b096a..6db3a58c 100644 --- a/script/vm/global.lua +++ b/script/vm/global.lua @@ -164,11 +164,9 @@ local function createGlobal(name, cate) }, mt) end ----@alias parser.enum string|integer - ---@class parser.object ---@field package _globalNode vm.global|false ----@field package _enums? parser.enum[] +---@field package _enums? parser.object[] ---@type table<string, vm.global> local allGlobals = {} @@ -378,22 +376,7 @@ local compilerGlobalSwitch = util.switch() for _, field in ipairs(tbl) do if field.type == 'tablefield' or field.type == 'tableindex' then - if not field.value then - goto CONTINUE - end - local key = guide.getKeyName(field) - if not key then - goto CONTINUE - end - if field.value.type == 'integer' - or field.value.type == 'string' then - source._enums[#source._enums+1] = field.value[1] - end - if field.value.type == 'binary' - or field.value.type == 'unary' then - source._enums[#source._enums+1] = vm.getNumber(field.value) - end - ::CONTINUE:: + source._enums[#source._enums+1] = field end end end) @@ -546,7 +529,7 @@ function vm.getGlobalNode(source) end ---@param source parser.object ----@return parser.enum[]? +---@return parser.object[]? function vm.getEnums(source) return source._enums end diff --git a/script/vm/type.lua b/script/vm/type.lua index 47bc1e4f..feaaca9e 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -53,22 +53,43 @@ local function checkEnum(parentName, child, uri) if not parentClass then return nil end - for _, set in ipairs(parentClass:getSets(uri)) do - if set.type == 'doc.enum' then - if not vm.getEnums(set) then - return false + local hasEnum + if child.type == 'global' then + ---@cast child vm.global + for _, set in ipairs(parentClass:getSets(uri)) do + if set.type == 'doc.enum' then + hasEnum = true + local enums = vm.getEnums(set) + if enums then + for _, enum in ipairs(enums) do + if vm.isSubType(uri, child, vm.compileNode(enum)) then + return true + end + end + end end - if child.type ~= 'string' - and child.type ~= 'doc.type.string' - and child.type ~= 'integer' - and child.type ~= 'number' - and child.type ~= 'doc.type.integer' then - return false + end + else + ---@cast child -vm.global + for _, set in ipairs(parentClass:getSets(uri)) do + if set.type == 'doc.enum' then + hasEnum = true + local myLiteral = vm.getInfer(child):viewLiterals() + local enums = vm.getEnums(set) + if enums then + for _, enum in ipairs(enums) do + if myLiteral == vm.getInfer(enum):viewLiterals() then + return true + end + end + end end - return util.arrayHas(vm.getEnums(set), child[1]) end end + if hasEnum then + return false + end return nil end @@ -269,7 +290,6 @@ function vm.isSubType(uri, child, parent, mark) return isEnum end - -- TODO: check duck if parentName == 'table' and not guide.isBasicType(childName) then return true end diff --git a/test/completion/common.lua b/test/completion/common.lua index dab31c31..b73543fb 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -3782,6 +3782,40 @@ f(<??>) } TEST [[ +local x = 1 +local y = 2 + +---@enum Enum +local t = { + x = x, + y = y, +} + +---@param p Enum +local function f(p) end + +f(<??>) +]] +{ + { + label = 't.x', + kind = define.CompletionItemKind.EnumMember, + }, + { + label = 't.y', + kind = define.CompletionItemKind.EnumMember, + }, + { + label = '1', + kind = define.CompletionItemKind.EnumMember, + }, + { + label = '2', + kind = define.CompletionItemKind.EnumMember, + }, +} + +TEST [[ -- <??> ]] |