summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-08-20 17:52:06 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-08-20 17:52:06 +0800
commitcb1a412bc7c205c73aec3ef2b1f8f8baf4564fb0 (patch)
tree1175e6ac7bbf1a0747780b8bad6728b8b4da5b00
parentfd86458f11ee270884af730a4344ac000265e64e (diff)
downloadlua-language-server-cb1a412bc7c205c73aec3ef2b1f8f8baf4564fb0.zip
stash
-rw-r--r--script/core/completion.lua8
-rw-r--r--script/core/hover/init.lua164
-rw-r--r--script/provider/markdown.lua9
-rw-r--r--script/provider/provider.lua10
-rw-r--r--test/crossfile/hover.lua21
-rw-r--r--test/hover/init.lua37
6 files changed, 81 insertions, 168 deletions
diff --git a/script/core/completion.lua b/script/core/completion.lua
index 06219e74..dc4ddf28 100644
--- a/script/core/completion.lua
+++ b/script/core/completion.lua
@@ -191,13 +191,7 @@ local function buildDesc(source)
return
end
local hover = getHover.get(source)
- local md = markdown()
- md:add('lua', hover.label)
- md:splitLine()
- md:add('md', hover.description)
- md:splitLine()
- md:add('lua', getSnip(source))
- return md
+ return hover
end
local function buildFunction(results, source, value, oop, data)
diff --git a/script/core/hover/init.lua b/script/core/hover/init.lua
index c6c2d92e..6e98d6c9 100644
--- a/script/core/hover/init.lua
+++ b/script/core/hover/init.lua
@@ -1,145 +1,55 @@
local files = require 'files'
-local searcher = require 'core.searcher'
local vm = require 'vm'
local getLabel = require 'core.hover.label'
local getDesc = require 'core.hover.description'
local util = require 'utility'
local findSource = require 'core.find-source'
-local lang = require 'language'
local markdown = require 'provider.markdown'
local infer = require 'core.infer'
-local function eachFunctionAndOverload(value, callback)
- callback(value)
- if not value.bindDocs then
- return
- end
- for _, doc in ipairs(value.bindDocs) do
- if doc.type == 'doc.overload' then
- callback(doc.overload)
- end
- end
-end
+local function getHover(source)
+ local md = markdown()
+ local defMark = {}
+ local labelMark = {}
+ local descMark = {}
-local function getHoverAsValue(source)
- local label = getLabel(source)
- local desc = getDesc(source)
- if not desc then
- local values = vm.getDefs(source)
- for _, def in ipairs(values) do
- desc = getDesc(def)
- if desc then
- break
- end
+ local function addHover(def)
+ if defMark[def] then
+ return
end
- end
- return {
- label = label,
- source = source,
- description = desc,
- }
-end
+ defMark[def] = true
-local function getHoverAsFunction(source)
- local values = vm.getDefs(source)
- local desc = getDesc(source)
- local labels = {}
- local defs = 0
- local protos = 0
- local other = 0
- local mark = {}
- for _, def in ipairs(values) do
- def = searcher.getObjectValue(def) or def
- if def.type == 'function'
- or def.type == 'doc.type.function' then
- eachFunctionAndOverload(def, function (value)
- if mark[value] then
- return
- end
- mark[value] =true
- local label = getLabel(value)
- if label then
- defs = defs + 1
- labels[label] = (labels[label] or 0) + 1
- if labels[label] == 1 then
- protos = protos + 1
- end
- end
- desc = desc or getDesc(value)
- end)
- elseif def.type == 'table'
- or def.type == 'boolean'
- or def.type == 'string'
- or def.type == 'integer'
- or def.type == 'number' then
- other = other + 1
- desc = desc or getDesc(def)
- end
- end
+ local label = getLabel(def)
+ local desc = getDesc(def)
- if defs == 0 then
- return getHoverAsValue(source)
- end
+ if not labelMark[tostring(label)] then
+ labelMark[tostring(label)] = true
+ md:add('lua', label)
+ md:splitLine()
+ end
- if defs == 1 and other == 0 then
- return {
- label = next(labels),
- source = source,
- description = desc,
- }
+ if not descMark[tostring(desc)] then
+ descMark[tostring(desc)] = true
+ md:add('md', desc)
+ md:splitLine()
+ end
end
- local lines = {}
- if defs > 1 then
- lines[#lines+1] = lang.script('HOVER_MULTI_DEF_PROTO', defs, protos)
- end
- if other > 0 then
- lines[#lines+1] = lang.script('HOVER_MULTI_PROTO_NOT_FUNC', other)
- end
- if defs > 1 then
- for label, count in util.sortPairs(labels) do
- lines[#lines+1] = ('(%d) %s'):format(count, label)
+ if infer.searchAndViewInfers(source) == 'function' then
+ for _, def in ipairs(vm.getDefs(source)) do
+ if def.type == 'function'
+ or def.type == 'doc.type.function' then
+ addHover(def)
+ end
end
else
- lines[#lines+1] = next(labels)
- end
- local label = table.concat(lines, '\n')
- return {
- label = label,
- source = source,
- description = desc,
- }
-end
-
-local function getHoverAsDocName(source)
- local label = getLabel(source)
- local desc = getDesc(source)
- return {
- label = label,
- source = source,
- description = desc,
- }
-end
-
-local function isFunction(source)
- local defs = vm.getAllDefs(source)
- for _, def in ipairs(defs) do
- if def.type == 'function' then
- return true
+ addHover(source)
+ for _, def in ipairs(vm.getDefs(source)) do
+ addHover(def)
end
end
- return false
-end
-local function getHover(source)
- if source.type == 'doc.type.name' then
- return getHoverAsDocName(source)
- end
- if isFunction(source) then
- return getHoverAsFunction(source)
- else
- return getHoverAsValue(source)
- end
+ return md
end
local accept = {
@@ -168,14 +78,12 @@ local function getHoverByUri(uri, offset)
end
local hover = getHover(source)
if SHOWSOURCE then
- hover.description = ('%s\n---\n\n```lua\n%s\n```'):format(
- hover.description or '',
- util.dump(source, {
- deep = 1,
- })
- )
+ hover:splitLine()
+ hover:add('lua', util.dump(source, {
+ deep = 1,
+ }))
end
- return hover
+ return hover, source
end
return {
diff --git a/script/provider/markdown.lua b/script/provider/markdown.lua
index 140267d7..3a215f0f 100644
--- a/script/provider/markdown.lua
+++ b/script/provider/markdown.lua
@@ -15,6 +15,7 @@ function mt:add(language, text)
if not text then
return
end
+ self._cacheResult = nil
if type(text) == 'table' then
self[#self+1] = {
type = 'markdown',
@@ -34,12 +35,16 @@ function mt:add(language, text)
end
function mt:splitLine()
+ self._cacheResult = nil
self[#self+1] = {
type = 'splitline',
}
end
function mt:string()
+ if self._cacheResult then
+ return self._cacheResult
+ end
local lines = {}
local language = 'md'
@@ -97,7 +102,9 @@ function mt:string()
end
end
- return table.concat(lines, '\n')
+ local result = table.concat(lines, '\n')
+ self._cacheResult = result
+ return result
end
return function ()
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index 09a031cc..6ffb0837 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -186,20 +186,16 @@ proto.on('textDocument/hover', function (params)
return nil
end
local offset = files.offsetOfWord(uri, params.position)
- local hover = core.byUri(uri, offset)
+ local hover, source = core.byUri(uri, offset)
if not hover then
return nil
end
- local md = markdown()
- md:add('lua', hover.label)
- md:splitLine()
- md:add('md', hover.description)
return {
contents = {
- value = md:string(),
+ value = tostring(hover),
kind = 'markdown',
},
- range = files.range(uri, hover.source.start, hover.source.finish),
+ range = files.range(uri, source.start, source.finish),
}
end)
diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua
index 04f7cc02..08773959 100644
--- a/test/crossfile/hover.lua
+++ b/test/crossfile/hover.lua
@@ -68,14 +68,8 @@ function TEST(expect)
local sourcePos = (sourceList[1][1] + sourceList[1][2]) // 2
local hover = core.byUri(sourceUri, sourcePos)
assert(hover)
- if hover.label then
- hover.label = hover.label:gsub('\r\n', '\n')
- end
- if hover.description then
- hover.description = tostring(hover.description)
- end
- assert(eq(hover.label, expect.hover.label))
- assert(eq(hover.description, expect.hover.description))
+ hover = tostring(hover):gsub('\r\n', '\n')
+ assert(eq(hover, expect.hover))
end
TEST {
@@ -87,10 +81,13 @@ TEST {
path = 'b.lua',
content = 'require <?"a"?>',
},
- hover = {
- label = '1 个字节',
- description = [[* [a.lua](file:///a.lua) (搜索路径: `?.lua`)]],
- }
+ hover = [[
+```lua
+1 个字节
+```
+
+---
+* [a.lua](file:///a.lua) (搜索路径: `?.lua`)]],
}
if require 'bee.platform'.OS == 'Windows' then
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 62db4b6d..3f07ea30 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -1,8 +1,25 @@
-local core = require 'core.hover'
-local files = require 'files'
+local core = require 'core.hover'
+local findSource = require 'core.find-source'
+local getLabel = require 'core.hover.label'
+local files = require 'files'
rawset(_G, 'TEST', true)
+local accept = {
+ ['local'] = true,
+ ['setlocal'] = true,
+ ['getlocal'] = true,
+ ['setglobal'] = true,
+ ['getglobal'] = true,
+ ['field'] = true,
+ ['method'] = true,
+ ['string'] = true,
+ ['number'] = true,
+ ['integer'] = true,
+ ['doc.type.name'] = true,
+ ['function'] = true,
+}
+
function TEST(script)
return function (expect)
files.removeAll()
@@ -14,7 +31,7 @@ function TEST(script)
local hover = core.byUri('', pos)
assert(hover)
expect = expect:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n')
- local label = hover.label:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n')
+ local label = tostring(hover):match('```lua[\r\n]*(.-)[\r\n]*```'):gsub('\r\n', '\n')
assert(expect == label)
end
end
@@ -571,9 +588,7 @@ end
<?F?>()
]]
[[
-(3 个定义,2 个原型)
-(2) function F(a: any)
-(1) function F(b: any)
+function F(a: any)
]]
-- 不根据参数推断
@@ -1278,9 +1293,7 @@ function f(x, y, z) end
print(<?f?>)
]]
[[
-(2 个定义,2 个原型)
-(1) function f(x: number, y: boolean, z: string)
-(1) function f(y: boolean)
+function f(x: number, y: boolean, z: string)
]]
TEST [[
@@ -1397,8 +1410,7 @@ local t = {}
function t.<?f?>() end
]]
[[
-(2 个定义,1 个原型)
-(2) function c.f()
+function c.f()
]]
TEST [[
@@ -1409,8 +1421,7 @@ t = {}
function t.<?f?>() end
]]
[[
-(2 个定义,1 个原型)
-(2) function t.f()
+function t.f()
]]
TEST [[