From 54b1e1123f242e5b5ffe8cc5ca51afe3cf18b4a1 Mon Sep 17 00:00:00 2001 From: sumneko Date: Fri, 11 Mar 2022 01:10:51 +0800 Subject: cleanup --- script/vm/compiler.lua | 41 ++++++++-------- script/vm/generic-manager.lua | 106 ------------------------------------------ script/vm/generic.lua | 25 +++++----- script/vm/global-manager.lua | 15 +++--- script/vm/node.lua | 2 +- script/vm/sign.lua | 98 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 145 deletions(-) delete mode 100644 script/vm/generic-manager.lua create mode 100644 script/vm/sign.lua (limited to 'script') diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index c7f5ad84..6be6e672 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -3,9 +3,10 @@ local util = require 'utility' local localID = require 'vm.local-id' local globalMgr = require 'vm.global-manager' local nodeMgr = require 'vm.node' -local genericMgr = require 'vm.generic-manager' +local signMgr = require 'vm.sign' local config = require 'config' local union = require 'vm.union' +local genericMgr = require 'vm.generic' ---@class parser.object ---@field _compiledNodes boolean @@ -143,30 +144,30 @@ function m.getClassFields(node, key, pushResult) end ---@class parser.object ----@field _generic? vm.node.generic-manager +---@field _sign? vm.sign ---@param source parser.object ----@return vm.node.generic-manager? -local function getObjectGeneric(source) - if source._generic ~= nil then - return source._generic +---@return vm.sign? +local function getObjectSign(source) + if source._sign ~= nil then + return source._sign end - source._generic = false + source._sign = false if source.type == 'function' then for _, doc in ipairs(source.bindDocs) do if doc.type == 'doc.generic' then - if not source._generic then - source._generic = genericMgr(source) + if not source._sign then + source._sign = signMgr() break end end end - if not source._generic then + if not source._sign then return false end for _, doc in ipairs(source.bindDocs) do if doc.type == 'doc.param' then - source._generic:addSign(doc.extends) + source._sign:addSign(doc.extends) end end end @@ -179,14 +180,14 @@ local function getObjectGeneric(source) if not hasGeneric then return false end - source._generic = genericMgr(source) + source._sign = signMgr() if source.type == 'doc.type.function' then for _, arg in ipairs(source.args) do - source._generic:addSign(arg.extends) + source._sign:addSign(arg.extends) end end end - return source._generic + return source._sign end local function getReturnOfFunction(func, index) @@ -209,11 +210,11 @@ local function getReturnOfFunction(func, index) return nil end local rtnNode = m.compileNode(rtn) - local generic = getObjectGeneric(func) - if not generic then + local sign = getObjectSign(func) + if not sign then return rtnNode end - return generic:getChild(rtnNode) + return genericMgr(rtnNode, sign) end end @@ -490,21 +491,21 @@ local compilerMap = util.switch() local index = source.index local hasMarkDoc if func.bindDocs then - local generic = getObjectGeneric(func) + local sign = getObjectSign(func) for _, doc in ipairs(func.bindDocs) do if doc.type == 'doc.return' then for _, rtn in ipairs(doc.returns) do if rtn.returnIndex == index then hasMarkDoc = true local hasGeneric - if generic then + if sign then guide.eachSourceType(rtn, 'doc.generic.name', function (src) hasGeneric = true end) end local rtnNode = m.compileNode(rtn) if hasGeneric then - nodeMgr.setNode(source, generic:getChild(rtnNode)) + nodeMgr.setNode(source, genericMgr(rtnNode, sign)) else nodeMgr.setNode(source, rtnNode) end diff --git a/script/vm/generic-manager.lua b/script/vm/generic-manager.lua deleted file mode 100644 index cad0e48d..00000000 --- a/script/vm/generic-manager.lua +++ /dev/null @@ -1,106 +0,0 @@ -local createGeneric = require 'vm.generic' -local guide = require 'parser.guide' -local nodeMgr = require 'vm.node' - ----@class vm.node.generic-manager ----@field parent parser.object ----@field signList vm.node[] -local mt = {} -mt.__index = mt -mt.type = 'generic-manager' - ----@param key parser.object -function mt:addSign(key) - local compiler = require 'vm.compiler' - self.signList[#self.signList+1] = compiler.compileNode(key) -end - ----@param node vm.node -function mt:getChild(node) - local generic = createGeneric(self, node) - return generic -end - ----@param argNodes vm.node[] ----@return table -function mt:resolve(argNodes) - if not argNodes then - return nil - end - local typeMgr = require 'vm.type' - local compiler = require 'vm.compiler' - local globalMgr = require 'vm.global-manager' - local resolved = {} - - ---@param typeUnit parser.object - ---@param node vm.node - local function resolve(typeUnit, node) - if typeUnit.type == 'doc.generic.name' then - local key = typeUnit[1] - if typeUnit.literal then - -- 'number' -> `T` - for n in nodeMgr.eachNode(node) do - if n.type == 'string' then - local type = globalMgr.declareGlobal('type', n[1], guide.getUri(n)) - resolved[key] = nodeMgr.mergeNode(type, resolved[key]) - end - end - else - -- number -> T - resolved[key] = nodeMgr.mergeNode(node, resolved[key]) - end - end - if typeUnit.type == 'doc.type.array' then - for n in nodeMgr.eachNode(node) do - if n.type == 'doc.type.array' then - -- number[] -> T[] - resolve(typeUnit.node, n.node) - end - end - end - if typeUnit.type == 'doc.type.table' then - for _, ufield in ipairs(typeUnit.fields) do - local ufieldNode = compiler.compileNode(ufield.name) - local uvalueNode = compiler.compileNode(ufield.extends) - if ufieldNode.type == 'doc.generic.name' and uvalueNode.type == 'doc.generic.name' then - -- { [number]: number} -> { [K]: V } - local tfieldNode = typeMgr.getTableKey(node, 'any') - local tvalueNode = typeMgr.getTableValue(node, 'any') - resolve(ufieldNode, tfieldNode) - resolve(uvalueNode, tvalueNode) - else - if ufieldNode.type == 'doc.generic.name' then - -- { [number]: number}|number[] -> { [K]: number } - local tnode = typeMgr.getTableKey(node, uvalueNode) - resolve(ufieldNode, tnode) - else - -- { [number]: number}|number[] -> { [number]: V } - local tnode = typeMgr.getTableValue(node, ufieldNode) - resolve(uvalueNode, tnode) - end - end - end - end - end - - for i, node in ipairs(argNodes) do - local sign = self.signList[i] - if not sign then - break - end - for n in nodeMgr.eachNode(sign) do - resolve(n, compiler.compileNode(node)) - end - end - - return resolved -end - ----@return vm.node.generic-manager -return function (parent) - local genericMgr = setmetatable({ - parent = parent, - signList = {}, - }, mt) - return genericMgr -end diff --git a/script/vm/generic.lua b/script/vm/generic.lua index e0096e30..aa1b76af 100644 --- a/script/vm/generic.lua +++ b/script/vm/generic.lua @@ -1,8 +1,11 @@ local nodeMgr = require 'vm.node' ----@class vm.node.generic ----@field parent vm.node.generic-manager ----@field node vm.node +---@class parser.object +---@field _generic vm.generic + +---@class vm.generic +---@field sign vm.sign +---@field proto vm.node local mt = {} mt.__index = mt mt.type = 'generic' @@ -107,14 +110,14 @@ end ---@param argNodes vm.node[] ---@return parser.object function mt:resolve(argNodes) - local resolved = self.parent:resolve(argNodes) - local newProto = cloneObject(self.node, resolved) + local resolved = self.sign:resolve(argNodes) + local newProto = cloneObject(self.proto, resolved) return newProto end function mt:eachNode() local nodes = {} - for n in nodeMgr.eachNode(self.parent) do + for n in nodeMgr.eachNode(self.proto) do nodes[#nodes+1] = n end local i = 0 @@ -124,13 +127,13 @@ function mt:eachNode() end end ----@param parent vm.node.generic-manager ----@param node vm.node -return function (parent, node) +---@param proto vm.node +---@param sign vm.sign +return function (proto, sign) local compiler = require 'vm.compiler' local generic = setmetatable({ - parent = parent, - node = compiler.compileNode(node), + sign = sign, + proto = compiler.compileNode(proto), }, mt) return generic end diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua index 2ffaf3da..3c42840c 100644 --- a/script/vm/global-manager.lua +++ b/script/vm/global-manager.lua @@ -1,7 +1,8 @@ local util = require 'utility' local guide = require 'parser.guide' local globalBuilder = require 'vm.global' -local genericMgr = require 'vm.generic-manager' +local signMgr = require 'vm.sign' +local genericMgr = require 'vm.generic' ---@class parser.object ---@field _globalNode vm.node.global @@ -145,14 +146,14 @@ local compilerGlobalMap = util.switch() source._globalNode = class if source.signs then - source._generic = genericMgr(source) + source._sign = signMgr() for _, sign in ipairs(source.signs) do - source._generic:addSign(sign) + source._sign:addSign(sign) end if source.extends then for _, ext in ipairs(source.extends) do if ext.type == 'doc.type.table' then - ext._generic = source._generic:getChild(ext) + ext._generic = genericMgr(ext, source._sign) end end end @@ -167,11 +168,11 @@ local compilerGlobalMap = util.switch() source._globalNode = alias if source.signs then - source._generic = genericMgr(source) + source._sign = signMgr() for _, sign in ipairs(source.signs) do - source._generic:addSign(sign) + source._sign:addSign(sign) end - source.extends._generic = source._generic:getChild(source.extends) + source.extends._generic = genericMgr(source.extends, source._sign) end end) : case 'doc.type.name' diff --git a/script/vm/node.lua b/script/vm/node.lua index a3cfb819..8766d347 100644 --- a/script/vm/node.lua +++ b/script/vm/node.lua @@ -1,6 +1,6 @@ local union = require 'vm.union' ----@alias vm.node parser.object | vm.node.union | vm.node.global | vm.node.generic | vm.node.generic-manager +---@alias vm.node parser.object | vm.node.union | vm.node.global | vm.generic ---@class vm.node-manager local m = {} diff --git a/script/vm/sign.lua b/script/vm/sign.lua new file mode 100644 index 00000000..aa1cf110 --- /dev/null +++ b/script/vm/sign.lua @@ -0,0 +1,98 @@ +local guide = require 'parser.guide' +local nodeMgr = require 'vm.node' + +---@class vm.sign +---@field parent parser.object +---@field signList vm.node[] +local mt = {} +mt.__index = mt +mt.type = 'sign' + +---@param key parser.object +function mt:addSign(key) + local compiler = require 'vm.compiler' + self.signList[#self.signList+1] = compiler.compileNode(key) +end + +---@param argNodes vm.node[] +---@return table +function mt:resolve(argNodes) + if not argNodes then + return nil + end + local typeMgr = require 'vm.type' + local compiler = require 'vm.compiler' + local globalMgr = require 'vm.global-manager' + local resolved = {} + + ---@param typeUnit parser.object + ---@param node vm.node + local function resolve(typeUnit, node) + if typeUnit.type == 'doc.generic.name' then + local key = typeUnit[1] + if typeUnit.literal then + -- 'number' -> `T` + for n in nodeMgr.eachNode(node) do + if n.type == 'string' then + local type = globalMgr.declareGlobal('type', n[1], guide.getUri(n)) + resolved[key] = nodeMgr.mergeNode(type, resolved[key]) + end + end + else + -- number -> T + resolved[key] = nodeMgr.mergeNode(node, resolved[key]) + end + end + if typeUnit.type == 'doc.type.array' then + for n in nodeMgr.eachNode(node) do + if n.type == 'doc.type.array' then + -- number[] -> T[] + resolve(typeUnit.node, n.node) + end + end + end + if typeUnit.type == 'doc.type.table' then + for _, ufield in ipairs(typeUnit.fields) do + local ufieldNode = compiler.compileNode(ufield.name) + local uvalueNode = compiler.compileNode(ufield.extends) + if ufieldNode.type == 'doc.generic.name' and uvalueNode.type == 'doc.generic.name' then + -- { [number]: number} -> { [K]: V } + local tfieldNode = typeMgr.getTableKey(node, 'any') + local tvalueNode = typeMgr.getTableValue(node, 'any') + resolve(ufieldNode, tfieldNode) + resolve(uvalueNode, tvalueNode) + else + if ufieldNode.type == 'doc.generic.name' then + -- { [number]: number}|number[] -> { [K]: number } + local tnode = typeMgr.getTableKey(node, uvalueNode) + resolve(ufieldNode, tnode) + else + -- { [number]: number}|number[] -> { [number]: V } + local tnode = typeMgr.getTableValue(node, ufieldNode) + resolve(uvalueNode, tnode) + end + end + end + end + end + + for i, node in ipairs(argNodes) do + local sign = self.signList[i] + if not sign then + break + end + for n in nodeMgr.eachNode(sign) do + resolve(n, compiler.compileNode(node)) + end + end + + return resolved +end + +---@return vm.sign +return function () + local genericMgr = setmetatable({ + signList = {}, + }, mt) + return genericMgr +end -- cgit v1.2.3