From 00dd1ed171beda2e892a2460d6e7eff321c775e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 8 Nov 2022 00:01:12 +0800 Subject: support enums with runtime values resolved #1411 --- script/vm/global.lua | 23 +++-------------------- script/vm/type.lua | 44 ++++++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 32 deletions(-) (limited to 'script/vm') 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 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 -- cgit v1.2.3