1
0

APIDump: Support structured parameter info.

Ref.: GH#3375
This commit is contained in:
Mattes D 2016-09-09 11:19:22 +02:00
parent c83b051c1a
commit 08861becc3
2 changed files with 140 additions and 41 deletions

View File

@ -52,14 +52,50 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
{
AddHook =
{
{ Params = "{{cPluginManager#Hooks|HookType}}, [HookFunction]", Return = "", IsStatic = true, Notes = "Informs the plugin manager that it should call the specified function when the specified hook event occurs. If a function is not specified, a default global function name is looked up, based on the hook type" },
{ Params = "{{cPlugin|Plugin}}, {{cPluginManager#Hooks|HookType}}, [HookFunction]", Return = "", IsStatic = true, Notes = "(<b>DEPRECATED</b>) Informs the plugin manager that it should call the specified function when the specified hook event occurs. If a function is not specified, a default function name is looked up, based on the hook type. NOTE: This format is deprecated and the server outputs a warning if it is used!" },
{
Params =
{
{ Name = "HookType", Type = "cPluginManager::PluginHook"},
{ Name = "Callback", Type = "callback", IsOptional = true},
},
IsStatic = true,
Notes = "Informs the plugin manager that it should call the specified function when the specified hook event occurs. If a function is not specified, a default global function name is looked up, based on the hook type",
},
},
BindCommand =
{
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", IsStatic = true, Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
{
Params =
{
{ Name = "Command", Type = "string"},
{ Name = "Permission", Type = "string"},
{ Name = "Callback", Type = "callback"},
{ Name = "HelpString", Type = "string"},
},
Return =
{
{ Type = "boolean" },
},
Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." ,
},
{
Params =
{
{ Name = "Command", Type = "string"},
{ Name = "Permission", Type = "string"},
{ Name = "Callback", Type = "callback"},
{ Name = "HelpString", Type = "string"},
},
Return =
{
{ Type = "boolean" },
},
IsStatic = true,
Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." ,
},
}, -- BindCommand
BindConsoleCommand =
{
{ Params = "Command, Callback, HelpString", Return = "[bool]", IsStatic = true, Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
@ -92,16 +128,6 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" },
UnloadPlugin = { Params = "PluginName", Return = "", Notes = "Queues the specified plugin to be unloaded. To avoid deadlocks, the unloading happens in the main tick thread asynchronously." },
},
ConstantGroups=
{
CommandResult =
{
Include = "^cr.*",
TextBefore = [[
Results that the (Force)ExecuteCommand return. This gives information if the command is executed or not and the reason.
]],
},
},
Constants =
{
crBlocked = { Notes = "When a plugin stopped the command using the OnExecuteCommand hook" },
@ -186,7 +212,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
ConstantGroups =
{
Hooks =
PluginHook =
{
Include = {"HOOK_.*"},
TextBefore = [[
@ -203,10 +229,8 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
},
CommandResult =
{
Include = {"cr.*"},
TextBefore = [[
These constants are returned by the ExecuteCommand() function to identify the exact outcome of the
operation.]],
Include = {"^cr.*"},
TextBefore = "Results that the (Force)ExecuteCommand functions return. This gives information whether the command was executed or not, and the reason.",
},
},
}, -- cPluginManager

View File

@ -146,6 +146,12 @@ local function CreateAPITables()
end
end
-- Remove the built-in Lua libraries:
API.debug = nil
API.io = nil
API.string = nil
API.table = nil
return API, Globals;
end
@ -676,13 +682,6 @@ local function ReadDescriptions(a_API, a_Desc)
-- Sort the functions (they may have been renamed):
table.sort(cls.Functions,
function(f1, f2)
if (f1.Name == f2.Name) then
-- Same name, either comparing the same function to itself, or two overloads, in which case compare the params
if ((f1.Params == nil) or (f2.Params == nil)) then
return 0;
end
return (f1.Params < f2.Params);
end
return (f1.Name < f2.Name);
end
);
@ -761,7 +760,86 @@ end
local function WriteHtmlClass(a_ClassAPI, a_ClassMenu)
--- Returns a HTML string describing the (parameter) type, linking to the type's documentation, if available
-- a_Type is the string containing the type (such as "cPlugin" or "number"), or nil
-- a_API is the complete API description (used for searching the classnames)
local function LinkifyType(a_Type, a_API)
-- Check params:
assert(type(a_Type) == "string")
assert(type(a_API) == "table")
-- If the type is a known class, return a direct link to it:
if (a_API[a_Type]) then
return "<a href=\"" .. a_Type .. ".html\">" .. a_Type .. "</a>"
end
-- If the type has a colon, it's a child enum of a class:
local idxColon = a_Type:find(":")
if (idxColon) then
local classType = a_Type:sub(1, idxColon - 1)
if (a_API[classType]) then
local enumType = a_Type:sub(idxColon + 2)
return "<a href=\"" .. classType .. ".html#" .. enumType .. "\">" .. a_Type .. "</a>"
end
end
-- Unknown or built-in type, output just text:
return a_Type
end
--- Returns an HTML string describing all function parameters (or return values)
-- a_FnParams is an array-table or string description of the parameters
-- a_ClassName is the name of the class for which the function is being documented (for Linkification)
-- a_API is the complete API description (for cross-type linkification)
local function CreateFunctionParamsDescription(a_FnParams, a_ClassName, a_API)
local pt = type(a_FnParams)
assert((pt == "string") or (pt == "table"))
assert(type(a_ClassName) == "string")
assert(type(a_API) == "table")
-- If the params description is a string (old format), just linkify it:
if (pt == "string") then
return LinkifyString(a_FnParams, a_ClassName)
end
-- If the params description is an empty table, give no description at all:
if not(a_FnParams[1]) then
return ""
end
-- The params description is a table, output the full desc:
local res = {"<table border=0 cellspacing=0>"}
local idx = 2
for _, param in ipairs(a_FnParams) do
res[idx] = "<tr><td>"
res[idx + 1] = param.Name or ""
res[idx + 2] = "</td><td><i>"
res[idx + 3] = LinkifyType(param.Type, a_API)
res[idx + 4] = "</i></td></tr>"
idx = idx + 5
end
res[idx] = "</tr></table>"
return table.concat(res)
end
--- Writes an HTML file containing the class API description for the given class
-- a_ClassAPI is the API description of the class to output
-- a_ClassMenu is the HTML string containing the code for the menu sidebar
-- a_API is the complete API (for cross-type linkification)
local function WriteHtmlClass(a_ClassAPI, a_ClassMenu, a_API)
-- Check params:
assert(type(a_ClassAPI) == "table")
assert(type(a_ClassMenu) == "string")
assert(type(a_API) == "table")
local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w");
if (cf == nil) then
LOGINFO("Cannot write HTML API for class " .. a_ClassAPI.Name .. ": " .. err)
@ -770,11 +848,12 @@ local function WriteHtmlClass(a_ClassAPI, a_ClassMenu)
-- Writes a table containing all functions in the specified list, with an optional "inherited from" header when a_InheritedName is valid
local function WriteFunctions(a_Functions, a_InheritedName)
if (#a_Functions == 0) then
if not(a_Functions[1]) then
-- No functions to write
return;
end
if (a_InheritedName ~= nil) then
if (a_InheritedName) then
cf:write("<h2>Functions inherited from ", a_InheritedName, "</h2>\n");
end
cf:write("<table>\n<tr><th>Name</th><th>Parameters</th><th>Return value</th><th>Notes</th></tr>\n");
@ -789,8 +868,8 @@ local function WriteHtmlClass(a_ClassAPI, a_ClassMenu)
TableOverloadedFunctions[func.Name] = (TableOverloadedFunctions[func.Name] or 0) + 1
-- Add the anchor names as a title
cf:write("<tr><td id=\"", func.Name, "_", TableOverloadedFunctions[func.Name], "\" title=\"", func.Name, "_", TableOverloadedFunctions[func.Name], "\">", func.Name, "</td>\n");
cf:write("<td>", LinkifyString(func.Params or "", (a_InheritedName or a_ClassAPI.Name)), "</td>\n");
cf:write("<td>", LinkifyString(func.Return or "", (a_InheritedName or a_ClassAPI.Name)), "</td>\n");
cf:write("<td>", CreateFunctionParamsDescription(func.Params or {}, a_InheritedName or a_ClassAPI.Name, a_API), "</td>\n");
cf:write("<td>", CreateFunctionParamsDescription(func.Return or {}, a_InheritedName or a_ClassAPI.Name, a_API), "</td>\n");
cf:write("<td>", StaticClause .. LinkifyString(func.Notes or "<i>(undocumented)</i>", (a_InheritedName or a_ClassAPI.Name)), "</td></tr>\n");
end
cf:write("</table>\n");
@ -1032,7 +1111,7 @@ local function WriteClasses(f, a_API, a_ClassMenu)
]]);
for _, cls in ipairs(a_API) do
f:write("<li><a href=\"", cls.Name, ".html\">", cls.Name, "</a></li>\n");
WriteHtmlClass(cls, a_ClassMenu);
WriteHtmlClass(cls, a_ClassMenu, a_API);
end
f:write([[
</ul></p>
@ -1648,14 +1727,10 @@ local function PrepareApi()
-- Load the API descriptions from the Classes and Hooks subfolders:
-- This needs to be done each time the command is invoked because the export modifies the tables' contents
local apiDesc = dofile(g_PluginFolder .. "/APIDesc.lua")
if (apiDesc.Classes == nil) then
apiDesc.Classes = {};
end
if (apiDesc.Hooks == nil) then
apiDesc.Hooks = {};
end
LoadAPIFiles("/Classes/", apiDesc.Classes);
LoadAPIFiles("/Hooks/", apiDesc.Hooks);
apiDesc.Classes = apiDesc.Classes or {}
apiDesc.Hooks = apiDesc.Hooks or {}
LoadAPIFiles("/Classes/", apiDesc.Classes)
LoadAPIFiles("/Hooks/", apiDesc.Hooks)
-- Reset the stats:
g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames.