diff options
-rw-r--r-- | script/core/completion.lua | 8 | ||||
-rw-r--r-- | script/core/hover/init.lua | 164 | ||||
-rw-r--r-- | script/provider/markdown.lua | 9 | ||||
-rw-r--r-- | script/provider/provider.lua | 10 | ||||
-rw-r--r-- | test/crossfile/hover.lua | 21 | ||||
-rw-r--r-- | test/hover/init.lua | 37 |
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 [[ |