summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-06-17 19:34:37 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-06-17 19:34:37 +0800
commit9978771a0f377c6f7663324e96e40f985fb99eb4 (patch)
tree11d3096fdea4d6f8ca7e9458198c859adaf72618 /script
parent2862d7cd292927b608523f5b8ede49c227e7065c (diff)
downloadlua-language-server-9978771a0f377c6f7663324e96e40f985fb99eb4.zip
improve
Diffstat (limited to 'script')
-rw-r--r--script/core/collector.lua7
-rw-r--r--script/core/noder.lua55
-rw-r--r--script/core/searcher.lua19
-rw-r--r--script/parser/guide.lua2
-rw-r--r--script/vm/getDocs.lua3
5 files changed, 58 insertions, 28 deletions
diff --git a/script/core/collector.lua b/script/core/collector.lua
index 763d145b..3293c9fe 100644
--- a/script/core/collector.lua
+++ b/script/core/collector.lua
@@ -49,22 +49,25 @@ function m.has(name)
return false
end
if next(nameCollect) == nil then
+ collect[name] = nil
return false
end
return true
end
+local DUMMY_FUNCTION = function () end
+
--- 迭代某个名字的订阅
---@param name string
function m.each(name)
local nameCollect = collect[name]
if not nameCollect then
- return function () end
+ return DUMMY_FUNCTION
end
local uri, value
return function ()
uri, value = next(nameCollect, uri)
- return value
+ return value, uri
end
end
diff --git a/script/core/noder.lua b/script/core/noder.lua
index 43d349ee..4c454d66 100644
--- a/script/core/noder.lua
+++ b/script/core/noder.lua
@@ -1,6 +1,7 @@
local util = require 'utility'
local guide = require 'parser.guide'
local collector = require 'core.collector'
+local files = require 'files'
local LastIDCache = {}
local FirstIDCache = {}
@@ -407,8 +408,8 @@ end
---添加关联单元
---@param noders noders
---@param source parser.guide.object
-function m.pushSource(noders, source)
- local id = m.getID(source)
+function m.pushSource(noders, source, id)
+ id = id or m.getID(source)
if not id then
return
end
@@ -517,11 +518,10 @@ local function compileCall(noders, call, sourceID, returnIndex)
pushForward(noders, sourceID, funcXID)
end
----@param uri uri
---@param noders noders
---@param source parser.guide.object
---@return parser.guide.object[]
-function m.compileNode(uri, noders, source)
+function m.compileNode(noders, source)
local id = getID(source)
bindValue(noders, source, id)
if source.special == 'setmetatable'
@@ -697,23 +697,34 @@ function m.compileNode(uri, noders, source)
pushForward(noders, keyID, 'dn:integer')
end
if source.type == 'doc.type.name' then
+ local uri = guide.getUri(source)
collector.subscribe(uri, id, getNode(noders, id))
end
- if source.type == 'doc.class.name' then
- collector.subscribe(uri, id, getNode(noders, id))
- collector.subscribe(uri, 'def:' .. id, getNode(noders, id))
- collector.subscribe(uri, 'def:dn', getNode(noders, id))
- end
- if source.type == 'doc.alias.name' then
+ if source.type == 'doc.class.name'
+ or source.type == 'doc.alias.name' then
+ local uri = guide.getUri(source)
collector.subscribe(uri, id, getNode(noders, id))
- collector.subscribe(uri, 'def:' .. id, getNode(noders, id))
- collector.subscribe(uri, 'def:dn', getNode(noders, id))
+
+ local defID = 'def:' .. id
+ collector.subscribe(uri, defID, getNode(noders, defID))
+ m.pushSource(noders, source, defID)
+
+ local defAnyID = 'def:dn:'
+ collector.subscribe(uri, defAnyID, getNode(noders, defAnyID))
+ m.pushSource(noders, source, defAnyID)
end
if guide.isGlobal(source) then
+ local uri = guide.getUri(source)
collector.subscribe(uri, id, getNode(noders, id))
if guide.isSet(source) then
- collector.subscribe(uri, 'def:' .. id, getNode(noders, id))
- collector.subscribe(uri, 'def:g', getNode(noders, id))
+
+ local defID = 'def:' .. id
+ collector.subscribe(uri, defID, getNode(noders, defID))
+ m.pushSource(noders, source, defID)
+
+ local defAnyID = 'def:g:'
+ collector.subscribe(uri, defAnyID, getNode(noders, defAnyID))
+ m.pushSource(noders, source, defAnyID)
end
end
-- 将函数的返回值映射到具体的返回值上
@@ -993,15 +1004,25 @@ function m.compileNodes(source)
if next(noders) then
return noders
end
- local uri = guide.getUri(root)
- collector.dropUri(uri)
log.debug('compileNodes:', guide.getUri(root))
guide.eachSource(root, function (src)
m.pushSource(noders, src)
- m.compileNode(uri, noders, src)
+ m.compileNode(noders, src)
end)
log.debug('compileNodes finish:', guide.getUri(root))
return noders
end
+files.watch(function (ev, uri)
+ uri = files.asKey(uri)
+ if ev == 'update' then
+ collector.dropUri(uri)
+ local state = files.getState(uri)
+ m.compileNodes(state.ast)
+ end
+ if ev == 'remove' then
+ collector.dropUri(uri)
+ end
+end)
+
return m
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 5a417765..b7c86262 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -477,21 +477,26 @@ function m.searchRefsByID(status, uri, expect, mode)
if FOOTPRINT then
status.footprint[#status.footprint+1] = ('checkGlobal:%s + %s, isCall: %s'):format(id, field, isCall, tid)
end
- for guri, def in collector.each(id) do
- if def then
- crossSearch(status, guri, tid, mode, uri)
+ local crossed = {}
+ for _, guri in collector.each('def:' .. id) do
+ if files.eq(uri, guri) then
goto CONTINUE
end
- if isCall then
+ crossed[guri] = true
+ crossSearch(status, guri, tid, mode, uri)
+ ::CONTINUE::
+ end
+ for _, guri in collector.each(id) do
+ if crossed[guri] then
goto CONTINUE
end
- if not field then
+ if isCall then
goto CONTINUE
end
- if mode == 'def' then
+ if not field and mode == 'def' then
goto CONTINUE
end
- if not files.eq(uri, guri) then
+ if files.eq(uri, guri) then
goto CONTINUE
end
crossSearch(status, guri, tid, mode, uri)
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index ad07e90e..227282bc 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -292,7 +292,7 @@ function m.getUri(obj)
end
local root = m.getRoot(obj)
if root then
- return root.uri
+ return root.uri or ''
end
return ''
end
diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua
index 16b82278..a17a89d2 100644
--- a/script/vm/getDocs.lua
+++ b/script/vm/getDocs.lua
@@ -10,12 +10,13 @@ local noder = require 'core.noder'
---@param name? string
---@return parser.guide.object[]
function vm.getDocDefines(name)
+ name = name or ''
local cache = vm.getCache 'getDocDefines'
if cache[name] then
return cache[name]
end
local results = {}
- local id = 'def:dn:' .. (name or '')
+ local id = 'def:dn:' .. name
for node in collector.each(id) do
if node.sources then
for _, source in ipairs(node.sources) do