diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-06-29 15:27:38 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-06-29 15:27:38 +0800 |
commit | f0bfb047bfb81b6f11400939ad736b7267e08938 (patch) | |
tree | 2b4d706f82485164363987bc9740d0ebd92787f8 /server | |
parent | 4586d62c06751d99199044375393dc1595375491 (diff) | |
download | lua-language-server-f0bfb047bfb81b6f11400939ad736b7267e08938.zip |
emmyfunction 支持多返回值
Diffstat (limited to 'server')
-rw-r--r-- | server/meta/Lua 5.4/basic.lua | 62 | ||||
-rw-r--r-- | server/meta/Lua 5.4/meta.lua | 17 | ||||
-rw-r--r-- | server/src/core/hover/emmy_function.lua | 11 | ||||
-rw-r--r-- | server/src/emmy/funcType.lua | 9 | ||||
-rw-r--r-- | server/src/parser/ast.lua | 14 | ||||
-rw-r--r-- | server/src/parser/grammar.lua | 11 | ||||
-rw-r--r-- | server/src/vm/emmy.lua | 38 |
7 files changed, 121 insertions, 41 deletions
diff --git a/server/meta/Lua 5.4/basic.lua b/server/meta/Lua 5.4/basic.lua index dcc3d580..7fa412de 100644 --- a/server/meta/Lua 5.4/basic.lua +++ b/server/meta/Lua 5.4/basic.lua @@ -8,17 +8,6 @@ arg = {} ---@return any function assert(v, message) end ----@alias GCOption string ----| > '"collect"' # 做一次完整的垃圾收集循环。 ----| '"stop"' # 停止垃圾收集器的运行。 ----| '"restart"' # 重启垃圾收集器的自动运行。 ----| '"count"' # 以 K 字节数为单位返回 Lua 使用的总内存数。 ----| '"step"' # 单步运行垃圾收集器。 ----| '"setpause"' # 设置收集器的 `间歇率`。 ----| '"setstepmul"' # 设置收集器的 `步进倍率`。 ----| '"incremental"' # 改变收集器模式为增量模式。 ----| '"generational"' # 改变收集器模式为分代模式。 ----| '"isrunning"' # 返回表示收集器是否在工作的布尔值。 ---@overload fun() ---@overload fun(opt:GCOption):any ---@param opt GCOption {optional = 'after'} @@ -27,14 +16,64 @@ function assert(v, message) end function collectgarbage(opt, arg) end --- 打开该名字的文件,并执行文件中的 Lua 代码块。 +---@overload fun():any ---@param filename string {optional = 'self', special = 'dofile:1'} ---@return any function dofile(filename) end +--- 中止上一次保护函数调用,将错误对象 `message` 返回。 +---@overload fun(message:any) +---@param message any +---@param level integer {optional = 'self'} +function error(message, level) end + --- 内部储存有全局环境。 _G = {} +--- 返回该对象的元表。 +---@param object any +---@return table {name = 'metatable'} +function getmetatable(object) end + +--- 能迭代表 `t` 中序列的键值对。 +---|```lua +---|for i, v in ipairs(t) do +---| -- body +---|end +---|``` +---@param t table +---@return {name = 'iterator'} +---@return table {name = 't'} +---@return integer {name = 'i'} +function ipairs(t) + --- 返回该键的下一个键及其关联的值。 + ---@overload fun(t:table):integer,any + ---@param t table + ---@param index any {optional = 'self'} + ---@return integer {name = 'index'} + ---@return any {name = 'value'} + local function iterator(t, index) end + + return iterator, t, nil +end + +--- 加载一个代码块。 +---@overload fun():function,string +---@overload fun(chunk:string|function):function,string +---@overload fun(chunk:string|function, chunkname:string):function,string +---@overload fun(chunk:string|function, chunkname:string, mode:loadOption):function,string +---@param chunk string|function +---@param chunkname string {optional = 'after'} +---@param mode loadOption {optional = 'after'} +---@param env table {optional = 'self'} +---@return {name = 'init'} +---@return string {name = 'errMessage', optional = 'self'} +function load(chunk, chunkname, mode, env) + return function (...) end +end + --- 返回该键的下一个键及其关联的值。 +---@overload fun(t:table):any, any ---@param t table ---@param index any {optional = 'self'} ---@return any {name = 'key'} @@ -53,6 +92,7 @@ function next(t, index) end ---@return any {name = 'key'} function pairs(t) --- 返回该键的下一个键及其关联的值。 + ---@overload fun(t:table):any, any ---@param t table ---@param index any {optional = 'self'} ---@return any {name = 'key'} diff --git a/server/meta/Lua 5.4/meta.lua b/server/meta/Lua 5.4/meta.lua index efa4dd08..4fe28af2 100644 --- a/server/meta/Lua 5.4/meta.lua +++ b/server/meta/Lua 5.4/meta.lua @@ -8,3 +8,20 @@ ---@class nil any ---@class userdata any ---@class thread any + +---@alias GCOption string +---| > '"collect"' # 做一次完整的垃圾收集循环。 +---| '"stop"' # 停止垃圾收集器的运行。 +---| '"restart"' # 重启垃圾收集器的自动运行。 +---| '"count"' # 以 K 字节数为单位返回 Lua 使用的总内存数。 +---| '"step"' # 单步运行垃圾收集器。 +---| '"setpause"' # 设置收集器的 `间歇率`。 +---| '"setstepmul"' # 设置收集器的 `步进倍率`。 +---| '"incremental"' # 改变收集器模式为增量模式。 +---| '"generational"' # 改变收集器模式为分代模式。 +---| '"isrunning"' # 返回表示收集器是否在工作的布尔值。 + +---@alias loadOption string +---| "'b'" # 只能是二进制代码块。 +---| "'t'" # 只能是文本代码块。 +---| > "'bt'" # 可以是二进制也可以是文本。 diff --git a/server/src/core/hover/emmy_function.lua b/server/src/core/hover/emmy_function.lua index 313b5276..4dd89107 100644 --- a/server/src/core/hover/emmy_function.lua +++ b/server/src/core/hover/emmy_function.lua @@ -41,11 +41,14 @@ local function buildEmmyArgs(emmy, object, select) end local function buildEmmyReturns(emmy) - local rtn = emmy:getReturn() - if rtn then - return '\n -> ' .. rtn:getType() - else + local rtns = {} + emmy:eachReturn(function (rtn) + rtns[#rtns+1] = rtn:getType() + end) + if #rtns == 0 then return '\n -> ' .. 'any' + else + return '\n -> ' .. table.concat(rtns, ', ') end end diff --git a/server/src/emmy/funcType.lua b/server/src/emmy/funcType.lua index f467f763..2c073fe2 100644 --- a/server/src/emmy/funcType.lua +++ b/server/src/emmy/funcType.lua @@ -30,7 +30,7 @@ function mt:addParam(name, type) end function mt:addReturn(type) - self._return = type + self._returns[#self._returns+1] = type end function mt:eachParam(callback) @@ -39,8 +39,10 @@ function mt:eachParam(callback) end end -function mt:getReturn() - return self._return +function mt:eachReturn(callback) + for _, rtn in ipairs(self._returns) do + callback(rtn) + end end function mt:bindFunction(func) @@ -55,6 +57,7 @@ return function (manager, source) local self = setmetatable({ source = source.id, _params = {}, + _returns = {}, _manager = manager, }, mt) return self diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua index b9cc9b47..f2486fd6 100644 --- a/server/src/parser/ast.lua +++ b/server/src/parser/ast.lua @@ -1213,16 +1213,22 @@ local Defs = { [2] = valueType, } end, - EmmyFunctionType = function (start, ...) + EmmyFunctionType = function (start, args, returns, finish) local result = { start = start, + finish = finish - 1, type = 'emmyFunctionType', - ... + args = args, + returns = returns, } - result.finish = result[#result] - 1 - result[#result] = nil return result end, + EmmyFunctionRtns = function (...) + return {...} + end, + EmmyFunctionArgs = function (...) + return {...} + end, EmmyAlias = function (name, emmyName, ...) return { type = 'emmyAlias', diff --git a/server/src/parser/grammar.lua b/server/src/parser/grammar.lua index e0db8988..c20f5b32 100644 --- a/server/src/parser/grammar.lua +++ b/server/src/parser/grammar.lua @@ -593,10 +593,15 @@ EmmyArrayType <- (MustEmmyName '[]') EmmyTableType <- ({} 'table' Cut '<' %s* EmmyType %s* ',' %s* EmmyType %s* '>' {}) -> EmmyTableType -EmmyFunctionType<- ({} 'fun' Cut %s* EmmyFunctionArgs? %s* EmmyFunctionRtn? {}) +EmmyFunctionType<- ({} 'fun' Cut %s* EmmyFunctionArgs %s* EmmyFunctionRtns {}) -> EmmyFunctionType -EmmyFunctionArgs<- '(' %s* EmmyFunctionArg %s* (',' %s* EmmyFunctionArg %s*)* ')' -EmmyFunctionRtn <- ':' %s* EmmyType +EmmyFunctionArgs<- ('(' %s* EmmyFunctionArg %s* (',' %s* EmmyFunctionArg %s*)* ')') + -> EmmyFunctionArgs + / '(' %nil ')'? + / %nil +EmmyFunctionRtns<- (':' %s* EmmyType (%s* ',' %s* EmmyType)*) + -> EmmyFunctionRtns + / %nil EmmyFunctionArg <- MustEmmyName %s* ':' %s* EmmyType EmmySee <- {} MustEmmyName %s* '#' %s* MustEmmyName {} diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua index 8625442b..5a15d3b0 100644 --- a/server/src/vm/emmy.lua +++ b/server/src/vm/emmy.lua @@ -299,23 +299,29 @@ function mt:buildEmmyFunctionType(source) local funcObj = emmyMgr:addFunctionType(source) ---@type emmyFunction local func = functionMgr.create(source) - for i = 1, #source // 2 do - local nameSource = source[i*2-1] - local typeSource = source[i*2] - local paramType = self:buildEmmyAnyType(typeSource) - funcObj:addParam(nameSource[1], paramType) - local value = self:createValue(paramType:getType(), typeSource) - value:setEmmy(paramType) - self:instantSource(nameSource) - func:addArg(nameSource[1], nameSource, value) + local args = source.args + if args then + for i = 1, #args // 2 do + local nameSource = args[i*2-1] + local typeSource = args[i*2] + local paramType = self:buildEmmyAnyType(typeSource) + funcObj:addParam(nameSource[1], paramType) + local value = self:createValue(paramType:getType(), typeSource) + value:setEmmy(paramType) + self:instantSource(nameSource) + func:addArg(nameSource[1], nameSource, value) + end end - local returnSource = source[#source] - if returnSource then - local returnType = self:buildEmmyAnyType(returnSource) - funcObj:addReturn(returnType) - local value = self:createValue(returnType:getType(), returnSource) - value:setEmmy(returnType) - func:setReturn(1, value) + local returns = source.returns + if returns then + for i = 1, #returns do + local returnSource = returns[i] + local returnType = self:buildEmmyAnyType(returnSource) + funcObj:addReturn(returnType) + local value = self:createValue(returnType:getType(), returnSource) + value:setEmmy(returnType) + func:setReturn(i, value) + end end funcObj:bindFunction(func) return funcObj |