275 lines
7.5 KiB
Lua
275 lines
7.5 KiB
Lua
local is_verbose = false
|
|
|
|
local M = {}
|
|
|
|
local stats = {}
|
|
|
|
local stats_pd = function(n)
|
|
local ret = 0
|
|
if n == 0 then
|
|
return 1
|
|
end
|
|
while (n ~= 0) do
|
|
n = math.floor(n / 10)
|
|
ret = ret + 1
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local fcol = 30
|
|
local ncol = 0
|
|
|
|
local get_percent = function(sv, svu)
|
|
return (sv == 0) and 100 or math.floor(((sv - svu) / sv) * 100 + 0.5)
|
|
end
|
|
|
|
local print_stat = function(printname, statname)
|
|
local sv = stats[statname] or 0
|
|
local svu = stats[statname .. "_undoc"] or 0
|
|
local percent = get_percent(sv, svu)
|
|
local tb = (" "):rep(math.max(0, fcol - #printname - 1) + ncol - stats_pd(sv))
|
|
local dtb = (" "):rep(ncol - stats_pd(sv - svu))
|
|
local ptb = (" "):rep(3 - stats_pd(percent))
|
|
print(("%s:%s%d (documented: %s%d or %s%d%%)")
|
|
:format(printname, tb, sv, dtb, sv - svu, ptb, percent))
|
|
end
|
|
|
|
local get_secstats = function(...)
|
|
local sv, svu = 0, 0
|
|
for i, v in ipairs({ ... }) do
|
|
sv = sv + (stats[v] or 0)
|
|
svu = svu + (stats[v .. "_undoc"] or 0)
|
|
end
|
|
return sv - svu, sv, get_percent(sv, svu)
|
|
end
|
|
|
|
M.print = function()
|
|
for k, v in pairs(stats) do
|
|
ncol = math.max(ncol, stats_pd(v))
|
|
end
|
|
|
|
print(("=== CLASS SECTION: %d out of %d (%d%%) ===\n")
|
|
:format(get_secstats("class", "interface", "mixin", "event")))
|
|
print_stat("Classes", "class")
|
|
print_stat("Interfaces", "interface")
|
|
print_stat("Mixins", "mixin")
|
|
print_stat("Events", "event")
|
|
|
|
print(("\n=== FUNCTION SECTION: %d out of %d (%d%%) ===\n")
|
|
:format(get_secstats("method", "param", "mret",
|
|
"getter", "gret", "gkey", "gvalue",
|
|
"setter", "sret", "skey", "svalue")))
|
|
print_stat("Methods", "method")
|
|
print_stat(" Method params", "param")
|
|
print_stat(" Method returns", "mret")
|
|
print_stat("Getters", "getter")
|
|
print_stat(" Getter returns", "gret")
|
|
print_stat(" Getter keys", "gkey")
|
|
print_stat(" Getter values", "gvalue")
|
|
print_stat("Setters", "setter")
|
|
print_stat(" Setter returns", "sret")
|
|
print_stat(" Setter keys", "skey")
|
|
print_stat(" Setter values", "svalue")
|
|
|
|
print(("\n=== TYPE SECTION: %d out of %d (%d%%) ===\n")
|
|
:format(get_secstats("alias", "struct", "sfield", "enum", "efield")))
|
|
print_stat("Aliases", "alias")
|
|
print_stat("Structs", "struct")
|
|
print_stat("Struct fields", "sfield")
|
|
print_stat("Enums", "enum")
|
|
print_stat("Enum fields", "efield")
|
|
|
|
print(("\n=== VARIABLE SECTION: %d out of %d (%d%%) ===\n")
|
|
:format(get_secstats("constant", "global")))
|
|
print_stat("Constants", "constant")
|
|
print_stat("Globals", "global")
|
|
|
|
local sv, svu = 0, 0
|
|
for k, v in pairs(stats) do
|
|
if k:match(".*_undoc$") then
|
|
svu = svu + v
|
|
else
|
|
sv = sv + v
|
|
end
|
|
end
|
|
print(("\n=== TOTAL: %d out of %d (%d%%) ===")
|
|
:format(sv - svu, sv, get_percent(sv, svu)))
|
|
end
|
|
|
|
local stat_incr = function(name, missing)
|
|
if not stats[name] then
|
|
stats[name], stats[name .. "_undoc"] = 0, 0
|
|
end
|
|
stats[name] = stats[name] + 1
|
|
if missing then
|
|
stats[name .. "_undoc"] = stats[name .. "_undoc"] + 1
|
|
end
|
|
end
|
|
|
|
local print_missing = function(name, tp)
|
|
if not is_verbose then
|
|
return
|
|
end
|
|
print(tp .. " '" .. name .. "'" .. " missing documentation")
|
|
end
|
|
|
|
M.check_class = function(cl)
|
|
local ct = cl:type_str_get()
|
|
if not ct then
|
|
return
|
|
end
|
|
if not cl:doc_get():exists() then
|
|
print_missing(cl:name_get(), ct)
|
|
stat_incr(ct, true)
|
|
else
|
|
stat_incr(ct, false)
|
|
end
|
|
|
|
for i, ev in ipairs(cl:events_get()) do
|
|
if not ev:doc_get():exists() then
|
|
print_missing(cl:name_get() .. "." .. ev:name_get(), "event")
|
|
stat_incr("event", true)
|
|
else
|
|
stat_incr("event", false)
|
|
end
|
|
end
|
|
end
|
|
|
|
M.check_method = function(fn, cl)
|
|
local fulln = cl:name_get() .. "." .. fn:name_get()
|
|
if fn:return_type_get(fn.METHOD) then
|
|
if not fn:return_doc_get(fn.METHOD):exists() then
|
|
print_missing(fulln, "method return")
|
|
stat_incr("mret", true)
|
|
else
|
|
stat_incr("mret", false)
|
|
end
|
|
end
|
|
if not fn:implement_get():doc_get(fn.METHOD):exists() then
|
|
print_missing(fulln, "method")
|
|
stat_incr("method", true)
|
|
else
|
|
stat_incr("method", false)
|
|
end
|
|
for i, p in ipairs(fn:parameters_get()) do
|
|
if not p:doc_get():exists() then
|
|
print_missing(fulln .. "." .. p:name_get(), "method parameter")
|
|
stat_incr("param", true)
|
|
else
|
|
stat_incr("param", false)
|
|
end
|
|
end
|
|
end
|
|
|
|
M.check_property = function(fn, cl, ft)
|
|
local pfxs = {
|
|
[fn.PROP_GET] = "g",
|
|
[fn.PROP_SET] = "s",
|
|
}
|
|
local pfx = pfxs[ft]
|
|
|
|
local fulln = cl:name_get() .. "." .. fn:name_get()
|
|
if fn:return_type_get(ft) then
|
|
if not fn:return_doc_get(ft):exists() then
|
|
print_missing(fulln, pfx .. "etter return")
|
|
stat_incr(pfx .. "ret", true)
|
|
else
|
|
stat_incr(pfx .. "ret", false)
|
|
end
|
|
end
|
|
|
|
local pimp = fn:implement_get()
|
|
|
|
if not pimp:doc_get(fn.PROPERTY):exists() and not pimp:doc_get(ft):exists() then
|
|
print_missing(fulln, pfx .. "etter")
|
|
stat_incr(pfx .. "etter", true)
|
|
else
|
|
stat_incr(pfx .. "etter", false)
|
|
end
|
|
|
|
for i, p in ipairs(fn:property_keys_get(ft)) do
|
|
if not p:doc_get():exists() then
|
|
print_missing(fulln .. "." .. p:name_get(), pfx .. "etter key")
|
|
stat_incr(pfx .. "key", true)
|
|
else
|
|
stat_incr(pfx .. "key", false)
|
|
end
|
|
end
|
|
|
|
for i, p in ipairs(fn:property_values_get(ft)) do
|
|
if not p:doc_get():exists() then
|
|
print_missing(fulln .. "." .. p:name_get(), pfx .. "etter value")
|
|
stat_incr(pfx .. "value", true)
|
|
else
|
|
stat_incr(pfx .. "value", false)
|
|
end
|
|
end
|
|
end
|
|
|
|
M.check_alias = function(v)
|
|
if not v:doc_get():exists() then
|
|
print_missing(v:name_get(), "alias")
|
|
stat_incr("alias", true)
|
|
else
|
|
stat_incr("alias", false)
|
|
end
|
|
end
|
|
|
|
M.check_struct = function(v)
|
|
if not v:doc_get():exists() then
|
|
print_missing(v:name_get(), "struct")
|
|
stat_incr("struct", true)
|
|
else
|
|
stat_incr("struct", false)
|
|
end
|
|
for i, fl in ipairs(v:struct_fields_get()) do
|
|
if not fl:doc_get():exists() then
|
|
print_missing(v:name_get() .. "." .. fl:name_get(), "struct field")
|
|
stat_incr("sfield", true)
|
|
else
|
|
stat_incr("sfield", false)
|
|
end
|
|
end
|
|
end
|
|
|
|
M.check_enum = function(v)
|
|
if not v:doc_get():exists() then
|
|
print_missing(v:name_get(), "enum")
|
|
stat_incr("enum", true)
|
|
else
|
|
stat_incr("enum", false)
|
|
end
|
|
for i, fl in ipairs(v:enum_fields_get()) do
|
|
if not fl:doc_get():exists() then
|
|
print_missing(v:name_get() .. "." .. fl:name_get(), "enum field")
|
|
stat_incr("efield", true)
|
|
else
|
|
stat_incr("efield", false)
|
|
end
|
|
end
|
|
end
|
|
|
|
M.check_constant = function(v)
|
|
if not v:doc_get():exists() then
|
|
print_missing(v:name_get(), "constant")
|
|
stat_incr("constant", true)
|
|
else
|
|
stat_incr("constant", false)
|
|
end
|
|
end
|
|
|
|
M.check_global = function(v)
|
|
if not v:doc_get():exists() then
|
|
print_missing(v:name_get(), "global")
|
|
stat_incr("global", true)
|
|
else
|
|
stat_incr("global", false)
|
|
end
|
|
end
|
|
|
|
M.init = function(verbose)
|
|
is_verbose = verbose
|
|
end
|
|
|
|
return M
|