diff options
Diffstat (limited to '')
-rw-r--r-- | Server/Plugins/APIDump/lualanguageserver.lua | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/Server/Plugins/APIDump/lualanguageserver.lua b/Server/Plugins/APIDump/lualanguageserver.lua new file mode 100644 index 000000000..2e1b86410 --- /dev/null +++ b/Server/Plugins/APIDump/lualanguageserver.lua @@ -0,0 +1,223 @@ +-- lualanguageserver.lua + +-- Implements the code for exporting definition files which can be used by a Lua-Language-Server + + + + + +--- Cleans up the name of a parameter so it can be used in a definition file +--- Removes anything containing brackets and removes dashes and spaces. +local function CleanupParameterName(paramName) + paramName = paramName:gsub("[%- ]", "") + :gsub("<.->.-</.->", ''); + return paramName +end + + + + + +--- Cleans up a description so it can be used in a definition file. +--- Uses the standard cleanup function but also removes any newlines. +local function CleanUpDescriptionLLS(a_Desc) + return CleanUpDescription(a_Desc) + :gsub("\n", " ") +end + + + + + +--- Writes a list of methods into the specified file in LLS format +local function WriteLLSMethods(f, a_NameSpace, a_Methods) + for _, func in ipairs(a_Methods or {}) do + f:write("\n---\n") + f:write("---", CleanUpDescriptionLLS(func.Notes or ""), "\n"); + f:write("---\n"); + local parameterList = {} + if (func.Params) then + local paramNr = 0; + for _, param in ipairs(func.Params) do + paramNr = paramNr + 1; + local paramName = CleanupParameterName(param.Name or ("param" .. paramNr)); + if (paramName:find("%.%.%.")) then + paramName = "..." + end + table.insert(parameterList, paramName) + if (param.IsOptional and paramName ~= "...") then + paramName = paramName .. "?" + end + + local paramType = param.Type; + if (paramType:find("%#")) then + paramType = paramType:match("%#(.+)"); + end + f:write("---@param ", paramName, " ", paramType, "\n"); + end + f:write("---\n"); + end + + if (func.Returns) then + for _, ret in ipairs(func.Returns) do + f:write("---@return ", ret.Type, "\n"); + end + f:write("---\n"); + end + local name = func.Name:find("constructor") and "__call" or func.Name; + name = name:find("operator") and "__meta" or name + local parameters = table.concat(parameterList, ", "); + f:write("function ") + if (a_NameSpace) then + f:write(a_NameSpace, ":") + end + f:write(name, "(", parameters, ") end\n\n"); + end +end + + + + + +--- Writes the list of constants. If the value is an enum the value is set from that enum. +--- This is a bit of a hack because Cuberite exports allot of enums as a constant inside +--- a class or global but documents them as if they are in their own table. +local function WriteLLSConstants(f, a_NameSpace, a_Constants, a_Enum) + if (not a_Constants) then + return; + end + + local prefix = "" + if (a_NameSpace) then + prefix = a_NameSpace .. "."; + end + for _, const in pairs(a_Constants) do + f:write(prefix) + if (a_Enum) then + f:write(const.Name, " = ", prefix, a_Enum, ".", const.Name, "\n") + else + local constValue = tostring(const.Value):match("[%w%d]+") or "nil"; + f:write(const.Name, " = ", constValue, "\n") + end + end +end + + + + + +--- Writes a list of constants into the specified file in LLS format +local function WriteLLSEnums(f, a_NameSpace, a_ConstantGroups) + if (not a_ConstantGroups) then + return; + end + + local prefix = ""; + if (a_NameSpace) then + prefix = a_NameSpace .. "." + end + for _, group in pairs(a_ConstantGroups) do + f:write("---@enum ", group.Name, "\n"); + f:write(prefix, group.Name, " = {\n") + for _, const in pairs(group.Constants) do + local constValue = tostring(const.Value):match("[%w%d]+") or "nil"; + f:write("\t", const.Name, " = ", constValue, ",\n") + end + f:write("}\n") + WriteLLSConstants(f, a_NameSpace, group.Constants, group.Name); + end +end + + + + + +--- Writes all the fields which a class has. +---@param f file* +---@param a_Variables table +local function WriteLLSVariables(f, a_Variables) + for _, variable in ipairs(a_Variables or {}) do + f:write("---@field ", variable.Name) + if (variable.Type) then + local type = variable.Type:match("%w+") + f:write(" ", type) + end + if (variable.Notes) then + f:write(" ", variable.Notes) + end + f:write("\n"); + end +end + + + + + +--- Writes one Cuberite class definition into the specified file in LLS format +local function WriteLLSClass(a_Class) + assert(type(a_Class) == "table") + + local f = io.open("LLS/cuberite/library/" .. a_Class.Name .. ".lua", "w"); + f:write("---@meta\n"); + f:write("\n\n---\n---The ", a_Class.Name, " namespace\n"); + + local inherit = ""; + if (a_Class.Inherits) then + inherit = ": " .. a_Class.Inherits.Name + end + f:write("---@class ", a_Class.Name, inherit, "\n"); + WriteLLSVariables(f, a_Class.Variables); + for _, func in pairs(a_Class.Functions or {}) do + if (func.Name:find("constructor")) then + local parameters = {}; + for _, param in ipairs(func.Parameters or {}) do + table.insert(parameters, param.Type); + end + f:write("---@operator call(", table.concat(parameters, ","), "):" .. a_Class.Name, "\n") + end + end + f:write("", a_Class.Name, " = {}\n"); + + -- Export methods and constants: + WriteLLSEnums(f, a_Class.Name, a_Class.ConstantGroups); + WriteLLSConstants(f, a_Class.Name, a_Class.Constants); + WriteLLSMethods(f, a_Class.Name, a_Class.Functions); + + f:close(); +end + + + + + +--- Dumps the entire API table into a file in the LLS format +function DumpAPILLS(a_API) + LOG("Dumping LLS API description...") + cFile:CreateFolderRecursive("LLS/cuberite/library"); + + -- Export each class except Globals, store those aside: + local Globals + for _, cls in ipairs(a_API) do + if (cls.Name ~= "Globals") then + WriteLLSClass(cls) + else + Globals = cls + end + end + + -- Export the globals: + if (Globals) then + local f = io.open("LLS/cuberite/library/Globals.lua", "w"); + f:write("---@meta\n\n"); + WriteLLSMethods(f, nil, Globals.Functions) + WriteLLSEnums(f, nil, Globals.ConstantGroups) + f:close(); + end + + -- Finish the file: + LOG("LLS API dumped...") +end + + + + |