summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-05-25 15:12:20 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-05-25 15:12:20 +0800
commit1c9c17bbcd55188b8fc770db96d02ddc3dad1854 (patch)
treeef6f05d5321711dad35ac2ce7b15775744f115f6
parent721d6fe207fe0fb4eaa16252e451814e61011c4a (diff)
downloadlua-language-server-1c9c17bbcd55188b8fc770db96d02ddc3dad1854.zip
update
-rw-r--r--script/core/hover/description.lua3
-rw-r--r--script/core/infer.lua54
-rw-r--r--script/core/noder.lua6
-rw-r--r--script/core/searcher.lua81
-rw-r--r--script/vm/eachField.lua2
-rw-r--r--test/hover/init.lua92
6 files changed, 156 insertions, 82 deletions
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 891d7cae..77c52de5 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -8,6 +8,7 @@ local config = require 'config'
local lang = require 'language'
local util = require 'utility'
local guide = require 'parser.guide'
+local noder = require 'core.noder'
local function asStringInRequire(source, literal)
local rootPath = ws.path or ''
@@ -128,7 +129,7 @@ local function tryDocClassComment(source)
for _, def in ipairs(vm.getDefs(source, 0)) do
if def.type == 'doc.class.name'
or def.type == 'doc.alias.name' then
- local class = searcher.getDocState(def)
+ local class = noder.getDocState(def)
local comment = getBindComment(class, class.bindGroup, class)
if comment then
return comment
diff --git a/script/core/infer.lua b/script/core/infer.lua
index 17935aa5..26380d58 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -159,7 +159,7 @@ end
local function searchLiteralOfValue(value, literals)
if value.type == 'string'
or value.type == 'boolean'
- or value.tyoe == 'number'
+ or value.type == 'number'
or value.type == 'integer' then
local v = value[1]
if v ~= nil then
@@ -271,6 +271,27 @@ function m.viewInfers(infers)
return infers[0]
end
+---合并对象的值
+---@param literals string[]
+---@return string
+function m.viewLiterals(literals)
+ if literals[0] then
+ return literals[0]
+ end
+ local result = {}
+ local count = 0
+ for infer in pairs(literals) do
+ count = count + 1
+ result[count] = infer
+ end
+ if count == 0 then
+ return nil
+ end
+ table.sort(result)
+ literals[0] = table.concat(result, '|')
+ return literals[0]
+end
+
local function getDocName(doc)
if not doc then
return nil
@@ -446,13 +467,27 @@ end
function m.searchLiterals(source)
local defs = searcher.requestDefinition(source)
local literals = {}
+ local mark = {}
+ mark[source] = true
searchLiteral(source, literals)
for _, def in ipairs(defs) do
- searchLiteral(def, literals)
+ if not mark[def] then
+ mark[def] = true
+ searchLiteral(def, literals)
+ end
end
return literals
end
+function m.searchAndViewLiterals(source)
+ if not source then
+ return nil
+ end
+ local literals = m.searchLiterals(source)
+ local view = m.viewLiterals(literals)
+ return view
+end
+
---判断对象的推断值是否是 true
---@param source parser.guide.object
function m.isTrue(source)
@@ -486,21 +521,6 @@ function m.searchAndViewInfers(source)
return view
end
-function m.searchAndViewLiterals(source)
- if not source then
- return nil
- end
- local result = {}
- local defs = vm.getDefs(source)
- for _, def in ipairs(defs) do
- if guide.isLiteral(def) and def[1] ~= nil then
- result[#result+1] = ('%q'):format(def[1])
- end
- end
- table.sort(result)
- return table.concat(result, '|')
-end
-
---搜索并显示推断的class
---@param source parser.guide.object
---@return string?
diff --git a/script/core/noder.lua b/script/core/noder.lua
index 12b8cd3d..11d20f40 100644
--- a/script/core/noder.lua
+++ b/script/core/noder.lua
@@ -828,6 +828,12 @@ function m.removeID(root, id)
noders[id] = nil
end
+---寻找doc的主体
+---@param doc parser.guide.object
+function m.getDocState(doc)
+ return getDocStateWithoutCrossFunction(doc)
+end
+
---获取对象的noders
---@param source parser.guide.object
---@return noders
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 11374b99..6e784e8c 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -541,11 +541,7 @@ function m.searchRefsByID(status, uri, expect, mode)
end
end
----搜索对象的引用
----@param status guide.status
----@param source parser.guide.object
----@param mode guide.searchmode
-function m.searchRefs(status, source, mode)
+local function prepareSearch(source)
if source.type == 'field'
or source.type == 'method' then
source = source.parent
@@ -554,24 +550,68 @@ function m.searchRefs(status, source, mode)
noder.compileNodes(root)
local uri = guide.getUri(source)
local id = noder.getID(source)
- if not id then
+ return uri, id
+end
+
+local function getField(source)
+ local field = source.next
+ if not field then
return
end
+ if field.type == 'getmethod'
+ or field.type == 'setmethod'
+ or field.type == 'getfield'
+ or field.type == 'setfield'
+ or field.type == 'getindex'
+ or field.type == 'setindex' then
+ return field
+ end
+end
+---搜索对象的引用
+---@param status guide.status
+---@param source parser.guide.object
+---@param mode guide.searchmode
+function m.searchRefs(status, source, mode)
+ local uri, id = prepareSearch(source)
+ if not id then
+ return
+ end
log.debug('searchRefs:', id)
m.searchRefsByID(status, uri, id, mode)
end
+---搜索对象的field
+---@param status guide.status
+---@param source parser.guide.object
+---@param mode guide.searchmode
+function m.searchFields(status, source, mode)
+ local uri, id = prepareSearch(source)
+ if not id then
+ return
+ end
+ m.searchRefsByID(status, uri, id, mode)
+ local results = status.results
+ for i = #results, 1, -1 do
+ local res = results[i]
+ local field = getField(res)
+ if field then
+ results[i] = field
+ else
+ results[i] = results[#results]
+ results[#results] = nil
+ end
+ end
+end
+
---@class guide.status
---搜索结果
---@field results parser.guide.object[]
---创建搜索状态
---@param parentStatus guide.status
----@param interface table
----@param deep integer
---@return guide.status
-function m.status(parentStatus, interface, deep)
+function m.status(parentStatus)
local status = {
--mark = parentStatus and parentStatus.mark or {},
callStack = {},
@@ -584,12 +624,10 @@ end
--- 请求对象的引用
---@param obj parser.guide.object
----@param interface table
----@param deep integer
---@return parser.guide.object[]
---@return integer
-function m.requestReference(obj, interface, deep)
- local status = m.status(nil, interface, deep)
+function m.requestReference(obj)
+ local status = m.status()
-- 根据 field 搜索引用
m.searchRefs(status, obj, 'ref')
@@ -598,16 +636,25 @@ end
--- 请求对象的定义
---@param obj parser.guide.object
----@param interface table
----@param deep integer
---@return parser.guide.object[]
---@return integer
-function m.requestDefinition(obj, interface, deep)
- local status = m.status(nil, interface, deep)
+function m.requestDefinition(obj)
+ local status = m.status()
-- 根据 field 搜索引用
m.searchRefs(status, obj, 'def')
return status.results, 0
end
+--- 请求对象的field
+function m.requestFields(obj, key)
+ if key then
+ error('not support')
+ end
+ local status = m.status()
+ m.searchFields(status, obj, 'ref')
+
+ return status.results
+end
+
return m
diff --git a/script/vm/eachField.lua b/script/vm/eachField.lua
index 9a40fb1c..7718f41e 100644
--- a/script/vm/eachField.lua
+++ b/script/vm/eachField.lua
@@ -19,7 +19,7 @@ local function getFields(source, deep, filterKey)
deep = config.config.intelliSense.searchDepth + (deep or 0)
await.delay()
- local results = searcher.requestFields(source, vm.interface, deep, filterKey)
+ local results = searcher.requestFields(source, filterKey)
unlock()
return results
diff --git a/test/hover/init.lua b/test/hover/init.lua
index adfa00bf..5ac33dd7 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -170,55 +170,55 @@ local <?obj?> = {}
]]
"local obj: {}"
-TEST [[
-local mt = {}
-mt.__name = 'class'
-
-local <?obj?> = setmetatable({}, mt)
-]]
-"local obj: class {}"
-
-TEST [[
-local mt = {}
-mt.name = 'class'
-mt.__index = mt
-
-local <?obj?> = setmetatable({}, mt)
-]]
-[[
-local obj: class {
- __index: table,
- name: string = "class",
-}
-]]
-
-TEST [[
-local mt = {}
-mt.TYPE = 'class'
-mt.__index = mt
+--TEST [[
+--local mt = {}
+--mt.__name = 'class'
+--
+--local <?obj?> = setmetatable({}, mt)
+--]]
+--"local obj: class {}"
-local <?obj?> = setmetatable({}, mt)
-]]
-[[
-local obj: class {
- TYPE: string = "class",
- __index: table,
-}
-]]
+--TEST [[
+--local mt = {}
+--mt.name = 'class'
+--mt.__index = mt
+--
+--local <?obj?> = setmetatable({}, mt)
+--]]
+--[[
+--local obj: class {
+-- __index: table,
+-- name: string = "class",
+--}
+--]]
-TEST [[
-local mt = {}
-mt.Class = 'class'
-mt.__index = mt
+--TEST [[
+--local mt = {}
+--mt.TYPE = 'class'
+--mt.__index = mt
+--
+--local <?obj?> = setmetatable({}, mt)
+--]]
+--[[
+--local obj: class {
+-- TYPE: string = "class",
+-- __index: table,
+--}
+--]]
-local <?obj?> = setmetatable({}, mt)
-]]
-[[
-local obj: class {
- Class: string = "class",
- __index: table,
-}
-]]
+--TEST [[
+--local mt = {}
+--mt.Class = 'class'
+--mt.__index = mt
+--
+--local <?obj?> = setmetatable({}, mt)
+--]]
+--[[
+--local obj: class {
+-- Class: string = "class",
+-- __index: table,
+--}
+--]]
-- TODO 支持自定义的函数库
--TEST[[