diff options
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/def.lua | 2 | ||||
-rw-r--r-- | script/vm/function.lua | 1 | ||||
-rw-r--r-- | script/vm/global.lua | 12 | ||||
-rw-r--r-- | script/vm/infer.lua | 2 | ||||
-rw-r--r-- | script/vm/node.lua | 4 | ||||
-rw-r--r-- | script/vm/ref.lua | 2 | ||||
-rw-r--r-- | script/vm/sign.lua | 29 | ||||
-rw-r--r-- | script/vm/type.lua | 33 | ||||
-rw-r--r-- | script/vm/value.lua | 8 |
9 files changed, 64 insertions, 29 deletions
diff --git a/script/vm/def.lua b/script/vm/def.lua index 03743826..a7af29b2 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -33,7 +33,7 @@ local searchFieldSwitch = util.switch() end end) : case 'global' - ---@param obj vm.object + ---@param obj vm.global ---@param key string : call(function (suri, obj, key, pushResult) if obj.cate == 'variable' then diff --git a/script/vm/function.lua b/script/vm/function.lua index e8fadb38..6c07acf6 100644 --- a/script/vm/function.lua +++ b/script/vm/function.lua @@ -62,6 +62,7 @@ function vm.countParamsOfNode(node) for n in node:eachObject() do if n.type == 'function' or n.type == 'doc.type.function' then + ---@cast n parser.object local fmin, fmax = vm.countParamsOfFunction(n) if not min or fmin < min then min = fmin diff --git a/script/vm/global.lua b/script/vm/global.lua index 50febd2c..b94e2768 100644 --- a/script/vm/global.lua +++ b/script/vm/global.lua @@ -162,6 +162,9 @@ local compilerGlobalSwitch = util.switch() : call(function (source) local uri = guide.getUri(source) local name = guide.getKeyName(source) + if not name then + return + end local global = vm.declareGlobal('variable', name, uri) global:addSet(uri, source) source._globalNode = global @@ -170,6 +173,9 @@ local compilerGlobalSwitch = util.switch() : call(function (source) local uri = guide.getUri(source) local name = guide.getKeyName(source) + if not name then + return + end local global = vm.declareGlobal('variable', name, uri) global:addGet(uri, source) source._globalNode = global @@ -272,6 +278,9 @@ local compilerGlobalSwitch = util.switch() : call(function (source) local uri = guide.getUri(source) local name = guide.getKeyName(source) + if not name then + return + end local class = vm.declareGlobal('type', name, uri) class:addSet(uri, source) source._globalNode = class @@ -294,6 +303,9 @@ local compilerGlobalSwitch = util.switch() : call(function (source) local uri = guide.getUri(source) local name = guide.getKeyName(source) + if not name then + return + end local alias = vm.declareGlobal('type', name, uri) alias:addSet(uri, source) source._globalNode = alias diff --git a/script/vm/infer.lua b/script/vm/infer.lua index e789214a..d6c4da44 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -443,7 +443,7 @@ function mt:viewClass() return table.concat(class, '|') end ----@param source parser.object +---@param source vm.node.object ---@param uri uri ---@return string? function vm.viewObject(source, uri) diff --git a/script/vm/node.lua b/script/vm/node.lua index fce8c642..2128edb2 100644 --- a/script/vm/node.lua +++ b/script/vm/node.lua @@ -11,7 +11,7 @@ vm.nodeCache = {} ---@class vm.node ---@field [integer] vm.node.object ----@field [vm.object] true +---@field [vm.node.object] true local mt = {} mt.__index = mt mt.id = 0 @@ -38,6 +38,7 @@ function mt:merge(node) end end else + ---@cast node -vm.node if not self[node] then self[node] = true self[#self+1] = node @@ -287,6 +288,7 @@ function mt:removeNode(node) self:remove 'false' end else + ---@cast c -vm.global self:removeObject(c) end end diff --git a/script/vm/ref.lua b/script/vm/ref.lua index c8b98acf..0135d11f 100644 --- a/script/vm/ref.lua +++ b/script/vm/ref.lua @@ -206,7 +206,7 @@ end ---@async ---@param source parser.object ---@param pushResult fun(src: parser.object) ----@param fileNotify fun(uri: uri): boolean +---@param fileNotify? fun(uri: uri): boolean function searchByParentNode(source, pushResult, defMap, fileNotify) nodeSwitch(source.type, source, pushResult, defMap, fileNotify) end diff --git a/script/vm/sign.lua b/script/vm/sign.lua index 0f5962fd..14d289eb 100644 --- a/script/vm/sign.lua +++ b/script/vm/sign.lua @@ -24,7 +24,7 @@ function mt:resolve(uri, args, removeGeneric) end local resolved = {} - ---@param object parser.object + ---@param object vm.node.object ---@param node vm.node local function resolve(object, node) if object.type == 'doc.generic.name' then @@ -33,6 +33,7 @@ function mt:resolve(uri, args, removeGeneric) -- 'number' -> `T` for n in node:eachObject() do if n.type == 'string' then + ---@cast n parser.object local type = vm.declareGlobal('type', n[1], guide.getUri(n)) resolved[key] = vm.createNode(type, resolved[key]) end @@ -57,6 +58,7 @@ function mt:resolve(uri, args, removeGeneric) end if n.type == 'global' and n.cate == 'type' then -- ---@field [integer]: number -> T[] + ---@cast n vm.global vm.getClassFields(uri, n, vm.declareGlobal('type', 'integer'), false, function (field) resolve(object.node, vm.compileNode(field.extends)) end) @@ -67,23 +69,37 @@ function mt:resolve(uri, args, removeGeneric) for _, ufield in ipairs(object.fields) do local ufieldNode = vm.compileNode(ufield.name) local uvalueNode = vm.compileNode(ufield.extends) - if ufieldNode:get(1).type == 'doc.generic.name' and uvalueNode:get(1).type == 'doc.generic.name' then + local firstField = ufieldNode:get(1) + local firstValue = uvalueNode:get(1) + if not firstField or not firstValue then + goto CONTINUE + end + if firstField.type == 'doc.generic.name' and firstValue.type == 'doc.generic.name' then -- { [number]: number} -> { [K]: V } local tfieldNode = vm.getTableKey(uri, node, 'any') local tvalueNode = vm.getTableValue(uri, node, 'any') - resolve(ufieldNode:get(1), tfieldNode) - resolve(uvalueNode:get(1), tvalueNode) + if tfieldNode then + resolve(firstField, tfieldNode) + end + if tvalueNode then + resolve(firstValue, tvalueNode) + end else if ufieldNode:get(1).type == 'doc.generic.name' then -- { [number]: number}|number[] -> { [K]: number } local tnode = vm.getTableKey(uri, node, uvalueNode) - resolve(ufieldNode:get(1), tnode) + if tnode then + resolve(firstField, tnode) + end elseif uvalueNode:get(1).type == 'doc.generic.name' then -- { [number]: number}|number[] -> { [number]: V } local tnode = vm.getTableValue(uri, node, ufieldNode) - resolve(uvalueNode:get(1), tnode) + if tnode then + resolve(firstValue, tnode) + end end end + ::CONTINUE:: end end end @@ -102,6 +118,7 @@ function mt:resolve(uri, args, removeGeneric) if obj.type == 'doc.type.table' or obj.type == 'doc.type.function' or obj.type == 'doc.type.array' then + ---@cast obj parser.object local hasGeneric guide.eachSourceType(obj, 'doc.generic.name', function (src) hasGeneric = true diff --git a/script/vm/type.lua b/script/vm/type.lua index d8adac6e..5211c3cb 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -2,7 +2,7 @@ local vm = require 'vm.vm' local guide = require 'parser.guide' ----@param object vm.object +---@param object vm.node.object ---@return string? local function getNodeName(object) if object.type == 'global' and object.cate == 'type' then @@ -39,18 +39,19 @@ local function getNodeName(object) end ---@param uri uri ----@param child vm.node|string|vm.object ----@param parent vm.node|string|vm.object +---@param child vm.node|string|vm.node.object +---@param parent vm.node|string|vm.node.object ---@param mark? table ---@return boolean function vm.isSubType(uri, child, parent, mark) mark = mark or {} if type(child) == 'string' then - child = vm.getGlobal('type', child) - if not child then + local global = vm.getGlobal('type', child) + if not global then return false end + child = global elseif child.type == 'vm.node' then for n in child:eachObject() do if getNodeName(n) @@ -67,10 +68,11 @@ function vm.isSubType(uri, child, parent, mark) end if type(parent) == 'string' then - parent = vm.getGlobal('type', parent) - if not parent then + local global = vm.getGlobal('type', parent) + if not global then return false end + parent = global elseif parent.type == 'vm.node' then for n in parent:eachObject() do if getNodeName(n) @@ -89,15 +91,17 @@ function vm.isSubType(uri, child, parent, mark) return false end - ---@cast child vm.object - ---@cast parent vm.object + ---@cast child vm.node.object + ---@cast parent vm.node.object local childName = getNodeName(child) local parentName = getNodeName(parent) if childName == 'any' or parentName == 'any' or childName == 'unknown' - or parentName == 'unknown' then + or parentName == 'unknown' + or not childName + or not parentName then return true end @@ -140,13 +144,12 @@ function vm.isSubType(uri, child, parent, mark) end end end - if set.type == 'doc.alias' and set.extends then - if vm.isSubType(uri, vm.compileNode(set.extends), parent, mark) then - return true - end + if set.type == 'doc.alias' then + return true end end end + mark[childName] = nil end return false @@ -204,7 +207,7 @@ end ---@param uri uri ---@param tnode vm.node ----@param vnode vm.node +---@param vnode vm.node|string|vm.object ---@return vm.node? function vm.getTableKey(uri, tnode, vnode) local result = vm.createNode() diff --git a/script/vm/value.lua b/script/vm/value.lua index e6e2045d..0ebf5d08 100644 --- a/script/vm/value.lua +++ b/script/vm/value.lua @@ -50,7 +50,7 @@ function vm.test(source) end end ----@param v vm.object +---@param v vm.node.object ---@return string? local function getUnique(v) if v.type == 'boolean' then @@ -79,11 +79,11 @@ local function getUnique(v) ---@cast v parser.object return ('func:%s@%d'):format(guide.getUri(v), v.start) end - return false + return nil end ----@param a vm.object? ----@param b vm.object? +---@param a parser.object? +---@param b parser.object? ---@return boolean|nil function vm.equal(a, b) if not a or not b then |