summaryrefslogtreecommitdiff
path: root/server/src/core/hover/emmy_function.lua
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-05-05 20:06:08 +0800
committersumneko <sumneko@hotmail.com>2019-05-05 20:06:08 +0800
commit6b95bb52f39082e9df605a954cb6a16d75b9611c (patch)
treec425335076a50e90f28f3c42ab825fb6c042c13b /server/src/core/hover/emmy_function.lua
parente00842cf43b6d2e2ff3900db32d3aa4e18a8f800 (diff)
downloadlua-language-server-6b95bb52f39082e9df605a954cb6a16d75b9611c.zip
emmyFunctionçš„hover
Diffstat (limited to 'server/src/core/hover/emmy_function.lua')
-rw-r--r--server/src/core/hover/emmy_function.lua123
1 files changed, 123 insertions, 0 deletions
diff --git a/server/src/core/hover/emmy_function.lua b/server/src/core/hover/emmy_function.lua
new file mode 100644
index 00000000..6306957f
--- /dev/null
+++ b/server/src/core/hover/emmy_function.lua
@@ -0,0 +1,123 @@
+---@param emmy EmmyFunctionType
+local function buildEmmyArgs(emmy, object, select)
+ local start
+ if object then
+ start = 2
+ else
+ start = 1
+ end
+ local strs = {}
+ local i = 0
+ emmy:eachParam(function (name, typeObj)
+ i = i + 1
+ if i > start then
+ strs[#strs+1] = ', '
+ end
+ if i == select then
+ strs[#strs+1] = '@ARG'
+ end
+ strs[#strs+1] = name .. ': ' .. typeObj:getType()
+ if i == select then
+ strs[#strs+1] = '@ARG'
+ end
+ end)
+ local text = table.concat(strs)
+ local argLabel = {}
+ for i = 1, 2 do
+ local pos = text:find('@ARG', 1, true)
+ if pos then
+ if i == 1 then
+ argLabel[i] = pos
+ else
+ argLabel[i] = pos - 1
+ end
+ text = text:sub(1, pos-1) .. text:sub(pos+4)
+ end
+ end
+ if #argLabel == 0 then
+ argLabel = nil
+ end
+ return text, argLabel
+end
+
+local function buildEmmyReturns(emmy)
+ return '\n -> ' .. emmy:getReturn():getType()
+end
+
+local function buildEnum(lib)
+ if not lib.enums then
+ return ''
+ end
+ local container = table.container()
+ for _, enum in ipairs(lib.enums) do
+ if not enum.name or (not enum.enum and not enum.code) then
+ goto NEXT_ENUM
+ end
+ if not container[enum.name] then
+ container[enum.name] = {}
+ if lib.args then
+ for _, arg in ipairs(lib.args) do
+ if arg.name == enum.name then
+ container[enum.name].type = arg.type
+ break
+ end
+ end
+ end
+ if lib.returns then
+ for _, rtn in ipairs(lib.returns) do
+ if rtn.name == enum.name then
+ container[enum.name].type = rtn.type
+ break
+ end
+ end
+ end
+ end
+ table.insert(container[enum.name], enum)
+ ::NEXT_ENUM::
+ end
+ local strs = {}
+ for name, enums in pairs(container) do
+ local tp
+ if type(enums.type) == 'table' then
+ tp = table.concat(enums.type, '/')
+ else
+ tp = enums.type
+ end
+ strs[#strs+1] = ('\n%s: %s'):format(name, tp or 'any')
+ for _, enum in ipairs(enums) do
+ if enum.default then
+ strs[#strs+1] = '\n -> '
+ else
+ strs[#strs+1] = '\n | '
+ end
+ if enum.code then
+ strs[#strs+1] = tostring(enum.code)
+ else
+ strs[#strs+1] = ('%q'):format(enum.enum)
+ end
+ if enum.description then
+ strs[#strs+1] = ' -- ' .. enum.description
+ end
+ end
+ end
+ return table.concat(strs)
+end
+
+return function (name, emmy, object, select)
+ local args, argLabel = buildEmmyArgs(emmy, object, select)
+ local returns = buildEmmyReturns(emmy)
+ local enum = buildEnum(emmy)
+ local tip = emmy.description
+ local headLen = #('function %s('):format(name)
+ local title = ('function %s(%s)%s'):format(name, args, returns)
+ if argLabel then
+ argLabel[1] = argLabel[1] + headLen
+ argLabel[2] = argLabel[2] + headLen
+ end
+ return {
+ label = title,
+ description = tip,
+ enum = enum,
+ argLabel = argLabel,
+ }
+end