diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2021-04-19 10:22:40 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2021-04-19 10:22:40 +0800 |
commit | 3c6f6a95ed5962bc8fe508ff39a207d542a6cfa1 (patch) | |
tree | ea37422475971018908487a7a85a2dd845c5d2f7 /script/core | |
parent | 776d25a2e68b86c2ac37357a71abcd4f2787498b (diff) | |
download | lua-language-server-3c6f6a95ed5962bc8fe508ff39a207d542a6cfa1.zip |
stash
Diffstat (limited to 'script/core')
-rw-r--r-- | script/core/guide.lua | 68 | ||||
-rw-r--r-- | script/core/linker.lua | 97 |
2 files changed, 95 insertions, 70 deletions
diff --git a/script/core/guide.lua b/script/core/guide.lua index 42ca624a..3f61e610 100644 --- a/script/core/guide.lua +++ b/script/core/guide.lua @@ -99,37 +99,22 @@ function m.searchRefs(status, source, mode) return end - ---@type link[] - local queue = {} - ---@type string - local expects = {} - local index = 0 + local search - ---添加到队列 - ---@param id string - ---@param expect string - local function pushQueue(id, expect) - index = index + 1 - queue[index] = id - expects[index] = expect - end - - local function pushQueueOfSource(obj, expect) + local function seachSource(obj, expect) local link = linker.getLink(obj) if not link then return end - pushQueue(link.id, expect or link.id) + search(link.id, expect or link.id) end - pushQueueOfSource(source) - local function checkForward(link, expect) if not link.forward then return end for _, forwardSources in ipairs(link.forward) do - pushQueueOfSource(forwardSources, expect) + seachSource(forwardSources, expect) end end @@ -138,46 +123,47 @@ function m.searchRefs(status, source, mode) return end for _, backSources in ipairs(link.backward) do - pushQueueOfSource(backSources, expect) + seachSource(backSources, expect) end end - ---@param link link + ---@param id string ---@param expect string - local function checkParentID(link, expect) - local parentID = link.parentID - if not parentID then + local function checkLastID(id, expect) + local lastID = linker.getLastID(root, id) + if not lastID then return end - expect = expect:sub(#parentID + 2) - pushQueue(parentID, expect) + expect = expect:sub(#lastID + 2) + pushQueue(lastID, expect) end - for _ = 1, 1000 do - if index <= 0 then - break - end - local link = queue[index] - local expect = expects[index] - index = index - 1 - local links = linker.getLinksBySource(link.source) + local stackCount = 0 + search = function (id, expect) + local links = linker.getLinksByID(root, id) if not links then - goto CONTINUE + return + end + if stackCount > 10 then + return end + stackCount = stackCount + 1 for _, eachLink in ipairs(links) do if expect == eachLink.id - or expect == '*' then + or expect == '' then m.pushResult(status, mode, eachLink.source) - checkForward(eachLink, '*') - checkBackward(eachLink, '*') + checkBackward(eachLink, '') + checkForward(eachLink, '') else - checkForward(eachLink, expect) checkBackward(eachLink, expect) + checkForward(eachLink, expect) end end - checkParentID(link, expect) - ::CONTINUE:: + --checkLastID(id, expect) + stackCount = stackCount - 1 end + + seachSource(source) end ---@class guide.status diff --git a/script/core/linker.lua b/script/core/linker.lua index b8a7139d..8642fba6 100644 --- a/script/core/linker.lua +++ b/script/core/linker.lua @@ -38,19 +38,19 @@ end local function checkMode(source) if source.type == 'setglobal' or source.type == 'getglobal' then - return 'g:' + return 'g' end if source.type == 'local' or source.type == 'setlocal' or source.type == 'getlocal' then - return 'l:' + return 'l' end if source.type == 'label' or source.type == 'goto' then - return 'l:' + return 'l' end if source.type == 'table' then - return 'l:' + return 'l' end return nil end @@ -80,6 +80,10 @@ local function checkForward(source) local list = TempList if source.value then list[#list+1] = source.value + elseif source.type == 'table' then + for _, keyvalue in ipairs(source) do + list[#list+1] = keyvalue + end end if #list == 0 then return nil @@ -143,18 +147,21 @@ local function getID(source) end util.revertTable(IDList) local id = table.concat(IDList, '|') - local parentID + local lastID, nextID if index > 1 then - parentID = table.concat(IDList, '|', 1, index) + lastID = table.concat(IDList, '|', 1, index) + nextID = table.concat(IDList, '|', 3) end - return id, current, parentID + return id, current, lastID, nextID end ---@class link -- 当前节点的id ---@field id string --- 父节点的id ----@field parentID string +-- 下个节点的id +---@field nextID string +-- 上个节点的id +---@field lastID string -- 语法树单元 ---@field source parser.guide.object -- 返回值,文件返回值总是0,函数返回值为第几个返回值 @@ -170,28 +177,36 @@ end ---@param source parser.guide.object ---@return link local function createLink(source) - local id, node, parentID = getID(source) + local id, node, lastID, nextID = getID(source) if not id then return nil end return { id = id, source = source, - parentID = parentID, + lastID = lastID, + nextID = nextID, freturn = checkFunctionReturn(node), forward = checkForward(source), backward = checkBackward(source), } end -local function insertLinker(linkers, mode, link) - local list = linkers[mode] - local id = link.id - if not list[id] then - list[id] = {} +---@param link link +local function insertLinker(linkers, link) + local idMap = linkers.idMap + local id = link.id + if not idMap[id] then + idMap[id] = {} + end + idMap[id][#idMap[id]+1] = link + link._links = idMap[id] + if link.lastID then + linkers.lastIDMap[id] = link.lastID + end + if link.nextID then + linkers.nextIDMap[id] = link.nextID end - list[id][#list[id]+1] = link - link._links = list[id] end local m = {} @@ -207,20 +222,42 @@ function m.getLinksBySource(source) end ---根据ID来获取所有的link ----@param source parser.guide.object ----@param mode string +---@param root parser.guide.object ---@param id string ---@return link[]? -function m.getLinksByID(source, mode, id) - local root = guide.getRoot(source) - if not root._linkers then +function m.getLinksByID(root, id) + root = guide.getRoot(root) + local linkers = root._linkers + if not linkers then + return nil + end + return linkers.idMap[id] +end + +---根据ID来获取上个节点的ID +---@param root parser.guide.object +---@param id string +---@return string +function m.getLastID(root, id) + root = guide.getRoot(root) + local linkers = root._linkers + if not linkers then return nil end - local linkers = root._linkers[mode] + return linkers.lastIDMap[id] +end + +---根据ID来获取前进的ID +---@param root parser.guide.object +---@param id string +---@return string +function m.getForwardID(root, id) + root = guide.getRoot(root) + local linkers = root._linkers if not linkers then return nil end - return linkers[id] + return linkers.nextIDMap[id] end ---获取source的链接信息 @@ -241,15 +278,17 @@ function m.compileLinks(source) if root._linkers then return root._linkers end - local linkers = {} + local linkers = { + idMap = {}, + lastIDMap = {}, + nextIDMap = {}, + } guide.eachSource(root, function (src) local link = m.getLink(src) if not link then return end - if link.mode then - insertLinker(linkers, link.mode, link) - end + insertLinker(linkers, link) end) root._linkers = linkers return linkers |