summaryrefslogtreecommitdiff
path: root/script/vm/compiler.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-07-11 19:34:41 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-07-11 19:34:41 +0800
commit6d040fd8da9f77c92a6359657c2d845c3b62735d (patch)
treee81ec976ad922c4bc74dedf29548f2a7c322f68e /script/vm/compiler.lua
parent41f0744c4e601ec80e63cce15b6e50f02f6e4a71 (diff)
downloadlua-language-server-6d040fd8da9f77c92a6359657c2d845c3b62735d.zip
fix #1311
Diffstat (limited to 'script/vm/compiler.lua')
-rw-r--r--script/vm/compiler.lua170
1 files changed, 106 insertions, 64 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 684ad9d0..1335ef7b 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -64,6 +64,90 @@ local function bindDocs(source)
return false
end
+---@param source parser.object
+---@param key any
+---@param ref boolean
+---@param pushResult fun(res: parser.object, markDoc?: boolean)
+local function searchFieldByLocalID(source, key, ref, pushResult)
+ local fields
+ if key then
+ fields = vm.getLocalSourcesSets(source, key)
+ if ref then
+ local gets = vm.getLocalSourcesGets(source, key)
+ if gets then
+ fields = fields or {}
+ for _, src in ipairs(gets) do
+ fields[#fields+1] = src
+ end
+ end
+ end
+ else
+ fields = vm.getLocalFields(source, false)
+ end
+ if not fields then
+ return
+ end
+ local hasMarkDoc = {}
+ for _, src in ipairs(fields) do
+ if src.bindDocs then
+ if bindDocs(src) then
+ local skey = guide.getKeyName(src)
+ if skey then
+ hasMarkDoc[skey] = true
+ end
+ pushResult(src, true)
+ end
+ end
+ end
+ for _, src in ipairs(fields) do
+ local skey = guide.getKeyName(src)
+ if not hasMarkDoc[skey] then
+ pushResult(src)
+ end
+ end
+end
+
+---@param suri uri
+---@param source parser.object
+---@param key any
+---@param ref boolean
+---@param pushResult fun(res: parser.object, markDoc?: boolean)
+local function searchFieldByGlobalID(suri, source, key, ref, pushResult)
+ local node = source._globalNode
+ if not node then
+ return
+ end
+ if node.cate == 'variable' then
+ if key then
+ if type(key) ~= 'string' then
+ return
+ end
+ local global = vm.getGlobal('variable', node.name, key)
+ if global then
+ for _, set in ipairs(global:getSets(suri)) do
+ pushResult(set)
+ end
+ for _, get in ipairs(global:getGets(suri)) do
+ pushResult(get)
+ end
+ end
+ else
+ local globals = vm.getGlobalFields('variable', node.name)
+ for _, global in ipairs(globals) do
+ for _, set in ipairs(global:getSets(suri)) do
+ pushResult(set)
+ end
+ for _, get in ipairs(global:getGets(suri)) do
+ pushResult(get)
+ end
+ end
+ end
+ end
+ if node.cate == 'type' then
+ vm.getClassFields(suri, node, key, ref, pushResult)
+ end
+end
+
local searchFieldSwitch = util.switch()
: case 'table'
: call(function (suri, source, key, ref, pushResult)
@@ -108,37 +192,6 @@ local searchFieldSwitch = util.switch()
vm.getClassFields(suri, stringlib, key, ref, pushResult)
end
end)
- : case 'local'
- : case 'self'
- : call(function (suri, node, key, ref, pushResult)
- local fields
- if key then
- fields = vm.getLocalSourcesSets(node, key)
- else
- fields = vm.getLocalFields(node, false)
- end
- if not fields then
- return
- end
- local hasMarkDoc = {}
- for _, src in ipairs(fields) do
- if src.bindDocs then
- if bindDocs(src) then
- local skey = guide.getKeyName(src)
- if skey then
- hasMarkDoc[skey] = true
- end
- pushResult(src, true)
- end
- end
- end
- for _, src in ipairs(fields) do
- local skey = guide.getKeyName(src)
- if not hasMarkDoc[skey] then
- pushResult(src)
- end
- end
- end)
: case 'doc.type.array'
: call(function (suri, source, key, ref, pushResult)
if type(key) == 'number' then
@@ -217,39 +270,8 @@ local searchFieldSwitch = util.switch()
end
end)
: default(function (suri, source, key, ref, pushResult)
- local node = source._globalNode
- if not node then
- return
- end
- if node.cate == 'variable' then
- if key then
- if type(key) ~= 'string' then
- return
- end
- local global = vm.getGlobal('variable', node.name, key)
- if global then
- for _, set in ipairs(global:getSets(suri)) do
- pushResult(set)
- end
- for _, get in ipairs(global:getGets(suri)) do
- pushResult(get)
- end
- end
- else
- local globals = vm.getGlobalFields('variable', node.name)
- for _, global in ipairs(globals) do
- for _, set in ipairs(global:getSets(suri)) do
- pushResult(set)
- end
- for _, get in ipairs(global:getGets(suri)) do
- pushResult(get)
- end
- end
- end
- end
- if node.cate == 'type' then
- vm.getClassFields(suri, node, key, ref, pushResult)
- end
+ searchFieldByLocalID(source, key, ref, pushResult)
+ searchFieldByGlobalID(suri, source, key, ref, pushResult)
end)
---@param suri uri
@@ -624,6 +646,7 @@ function vm.compileByParentNode(source, key, ref, pushResult)
local parentNode = vm.compileNode(source)
local docedResults = {}
local commonResults = {}
+ local mark = {}
local suri = guide.getUri(source)
local hasClass
for node in parentNode:eachObject() do
@@ -645,6 +668,10 @@ function vm.compileByParentNode(source, key, ref, pushResult)
)
or guide.isLiteral(node) then
searchFieldSwitch(node.type, suri, node, key, ref, function (res, markDoc)
+ if mark[res] then
+ return
+ end
+ mark[res] = true
if markDoc then
docedResults[#docedResults+1] = res
else
@@ -653,6 +680,21 @@ function vm.compileByParentNode(source, key, ref, pushResult)
end)
end
end
+
+ if not next(mark) then
+ searchFieldByLocalID(source, key, ref, function (res, markDoc)
+ if mark[res] then
+ return
+ end
+ mark[res] = true
+ if markDoc then
+ docedResults[#docedResults+1] = res
+ else
+ commonResults[#commonResults+1] = res
+ end
+ end)
+ end
+
if #docedResults > 0 then
for _, res in ipairs(docedResults) do
pushResult(res)