summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-12-12 20:19:44 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-12-12 20:19:44 +0800
commite4357d4cd7ee9018372b8e8231686888304a05d1 (patch)
tree283b38b8185a4261ea90752ea2c159bdf29e6310 /server/src
parentee7ddabf22768c57952e89098db9ffea84475ff7 (diff)
downloadlua-language-server-e4357d4cd7ee9018372b8e8231686888304a05d1.zip
hover支持自定义函数
Diffstat (limited to 'server/src')
-rw-r--r--server/src/matcher/hover.lua100
-rw-r--r--server/src/matcher/vm.lua29
2 files changed, 126 insertions, 3 deletions
diff --git a/server/src/matcher/hover.lua b/server/src/matcher/hover.lua
index f2b0f07d..f93ade65 100644
--- a/server/src/matcher/hover.lua
+++ b/server/src/matcher/hover.lua
@@ -178,8 +178,102 @@ local function getLibHover(lib, fullKey, oo)
return cache[lib]
end
+local function buildValueName(result, source)
+ local func = result.value
+ local declarat = func.declarat or source
+ if declarat then
+ local key
+ if declarat.type == 'name' then
+ key = declarat[1]
+ elseif declarat.type == 'string' then
+ key = ('%q'):format(declarat[1])
+ elseif declarat.type == 'number' or declarat.type == 'boolean' then
+ key = tostring(declarat[1])
+ else
+ key = '?'
+ end
+ if source.object then
+ return declarat.parentName .. ':' .. key
+ else
+ if declarat.parentName then
+ if declarat.index then
+ return declarat.parentName .. '[' .. key .. ']'
+ else
+ return declarat.parentName .. '.' .. key
+ end
+ else
+ return key
+ end
+ end
+ end
+ return result.key or ''
+end
+
+local function buildValueArgs(result)
+ local func = result.value
+ local names = {}
+ local values = {}
+ if func.args then
+ for i, arg in ipairs(func.args) do
+ if arg.type == '...' then
+ names[i] = '...'
+ else
+ names[i] = arg.key
+ end
+ end
+ end
+ if func.argValues then
+ for i, value in ipairs(func.argValues) do
+ values[i] = value.type
+ if values[i] == 'nil' then
+ values[i] = 'any'
+ end
+ end
+ end
+ local strs = {}
+ for i = 1, math.max(#names, #values) do
+ local name = names[i] or '?'
+ local value = values[i] or 'any'
+ strs[i] = name .. ': ' .. value
+ end
+ return table.concat(strs, ', ')
+end
+
+local function buildValueReturns(result)
+ local func = result.value
+ if not func.hasReturn then
+ return ''
+ end
+ local strs = {}
+ for i, rtn in ipairs(func.returns) do
+ strs[i] = rtn.type
+ if strs[i] == 'nil' then
+ strs[i] = 'any'
+ end
+ end
+ return '\n -> ' .. table.concat(strs, ', ')
+end
+
+local function buildValueFunctionHover(result, source)
+ local name = buildValueName(result, source)
+ local args = buildValueArgs(result)
+ local returns = buildValueReturns(result)
+ local title = ('function %s(%s)%s'):format(name, args, returns)
+ return ([[
+```lua
+%s
+```
+]]):format(title)
+end
+
+local function getValueHover(result, source)
+ if result.value.type == 'function' then
+ return buildValueFunctionHover(result, source)
+ end
+end
+
return function (vm, pos)
- local result = findResult(vm, pos)
+ local result, source = findResult(vm, pos)
if not result then
return nil
end
@@ -189,4 +283,8 @@ return function (vm, pos)
local hover = getLibHover(lib, fullKey, oo)
return hover
end
+
+ if result.value then
+ return getValueHover(result, source)
+ end
end
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua
index 5fd5e0d9..3f1e7d2a 100644
--- a/server/src/matcher/vm.lua
+++ b/server/src/matcher/vm.lua
@@ -197,6 +197,9 @@ function mt:setValue(var, value, source)
end
if source and source.start then
self:addInfo(var, 'set', source)
+ if not value.declarat then
+ value.declarat = source
+ end
end
return value
end
@@ -333,7 +336,9 @@ function mt:getFunctionArg(func, i)
func.argValues = {}
end
if not func.argValues[i] then
- func.argValues[i] = self:createValue('nil')
+ for n = #func.argValues+1, i do
+ func.argValues[n] = self:createValue('nil')
+ end
end
return func.argValues[i]
end
@@ -410,6 +415,7 @@ function mt:getCurrentFunction()
end
function mt:setFunctionReturn(func, index, value)
+ func.hasReturn = true
if not func.returns then
func.returns = {
type = 'list',
@@ -438,7 +444,9 @@ function mt:getFunctionReturns(func, i)
end
if i then
if not func.returns[i] then
- func.returns[i] = self:createValue('nil')
+ for n = #func.returns+1, i do
+ func.returns[n] = self:createValue('nil')
+ end
end
return func.returns[i]
else
@@ -583,10 +591,13 @@ end
function mt:getSimple(simple, mode)
local value = self:getExp(simple[1])
local field
+ local parentName
if simple[1].type == 'name' then
field = self:getName(simple[1][1])
+ parentName = field.key
else
field = self:createValue('nil', simple[1])
+ parentName = '?'
end
local object
for i = 2, #simple do
@@ -607,6 +618,7 @@ function mt:getSimple(simple, mode)
call = obj,
lastobj = simple[i-1],
}
+ parentName = parentName .. '(...)'
elseif obj.index then
local index = self:getIndex(obj)
field = self:getField(value, index, obj)
@@ -616,6 +628,16 @@ function mt:getSimple(simple, mode)
self:addInfo(field, 'get', obj)
end
end
+ obj.object = object
+
+ obj.parentName = parentName
+ if obj.type == 'string' then
+ parentName = ('%s[%q]'):format(parentName, index)
+ elseif obj.type == 'number' or obj.type == 'boolean' then
+ parentName = ('%s[%s]'):format(parentName, index)
+ else
+ parentName = ('%s[?]'):format(parentName)
+ end
else
if tp == 'name' then
field = self:getField(value, obj[1], obj)
@@ -623,6 +645,9 @@ function mt:getSimple(simple, mode)
if mode == 'value' or i < #simple then
self:addInfo(field, 'get', obj)
end
+ obj.object = object
+ obj.parentName = parentName
+ parentName = parentName .. '.' .. field.key
elseif tp == ':' then
object = field
end