diff options
-rw-r--r-- | script/core/noder.lua | 2 | ||||
-rw-r--r-- | script/core/searcher.lua | 56 | ||||
-rw-r--r-- | script/parser/ast.lua | 1 |
3 files changed, 50 insertions, 9 deletions
diff --git a/script/core/noder.lua b/script/core/noder.lua index fa9d7d72..12b8cd3d 100644 --- a/script/core/noder.lua +++ b/script/core/noder.lua @@ -139,7 +139,7 @@ local function getKey(source) return '', tbl end end - return source.start, nil + return source.finish, nil elseif source.type == 'doc.class.name' or source.type == 'doc.alias.name' or source.type == 'doc.extends.name' diff --git a/script/core/searcher.lua b/script/core/searcher.lua index ccb5814b..11374b99 100644 --- a/script/core/searcher.lua +++ b/script/core/searcher.lua @@ -202,11 +202,33 @@ local function crossSearch(status, uri, expect, mode) m.searchRefsByID(status, uri, expect, mode) end +local function getLock(status, uri, expect, mode) + local slock = status.lock + local ulock = slock[uri] + if not ulock then + ulock = {} + slock[uri] = ulock + end + local mlock = ulock[mode] + if not mlock then + mlock = {} + ulock[mode] = mlock + end + if mlock[expect] then + return false + end + mlock[expect] = true + return true +end + function m.searchRefsByID(status, uri, expect, mode) local ast = files.getAst(uri) if not ast then return end + if not getLock(status, uri, expect, mode) then + return + end local root = ast.ast local searchStep noder.compileNodes(root) @@ -400,10 +422,10 @@ function m.searchRefsByID(status, uri, expect, mode) return end local firstID = noder.getFirstID(id) - if status.crossedGlobal[firstID] then + if status.crossed[firstID] then return end - status.crossedGlobal[firstID] = true + status.crossed[firstID] = true local tid = id .. (field or '') for guri in files.eachFile() do if not files.eq(uri, guri) then @@ -417,10 +439,10 @@ function m.searchRefsByID(status, uri, expect, mode) return end local firstID = noder.getFirstID(id) - if status.crossedClass[firstID] then + if status.crossed[firstID] then return end - status.crossedClass[firstID] = true + status.crossed[firstID] = true local tid = id .. (field or '') for guri in files.eachFile() do if not files.eq(uri, guri) then @@ -429,6 +451,23 @@ function m.searchRefsByID(status, uri, expect, mode) end end + local function checkMainReturn(id, node, field) + if id ~= 'mainreturn' then + return + end + if mode ~= 'ref' and not field then + return + end + local calls = vm.getLinksTo(uri) + for _, call in ipairs(calls) do + local turi = guide.getUri(call) + if not files.eq(turi, uri) then + local tid = noder.getID(call) .. (field or '') + crossSearch(status, turi, tid, mode) + end + end + end + local function searchNode(id, node, field) if node.call then callStack[#callStack+1] = node.call @@ -456,6 +495,7 @@ function m.searchRefsByID(status, uri, expect, mode) checkGlobal(id, node, field) checkClass(id, node, field) + checkMainReturn(id, node, field) if node.call then callStack[#callStack] = nil @@ -534,10 +574,10 @@ end function m.status(parentStatus, interface, deep) local status = { --mark = parentStatus and parentStatus.mark or {}, - callStack = {}, - crossedGlobal = {}, - crossedClass = {}, - results = {}, + callStack = {}, + crossed = {}, + lock = {}, + results = {}, } return status end diff --git a/script/parser/ast.lua b/script/parser/ast.lua index b029b1ec..40b5788e 100644 --- a/script/parser/ast.lua +++ b/script/parser/ast.lua @@ -1467,6 +1467,7 @@ local Defs = { end call.node = func call.start = inA + call.finish = doB - 1 func.next = call func.iterator = true values = { call } |