From 34ef9c313989402d523951b2c20c7141d3bdce78 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Tue, 21 May 2019 15:43:02 +0200 Subject: [PATCH] docs: remove obsolete docgen from the tree This has long been replaced with tools/edocgen.git and most likely does not even work. --- src/Makefile_Elua.am | 15 +- src/scripts/elua/apps/README-docgen.md | 9 - src/scripts/elua/apps/docgen/doctree.lua | 1427 ----------------- src/scripts/elua/apps/docgen/keyref.lua | 41 - src/scripts/elua/apps/docgen/mono.lua | 614 -------- src/scripts/elua/apps/docgen/stats.lua | 274 ---- src/scripts/elua/apps/docgen/util.lua | 50 - src/scripts/elua/apps/docgen/writer.lua | 397 ----- src/scripts/elua/apps/gendoc.lua | 1804 ---------------------- src/scripts/elua/apps/gendoc.sh | 38 - 10 files changed, 1 insertion(+), 4668 deletions(-) delete mode 100644 src/scripts/elua/apps/README-docgen.md delete mode 100644 src/scripts/elua/apps/docgen/doctree.lua delete mode 100644 src/scripts/elua/apps/docgen/keyref.lua delete mode 100644 src/scripts/elua/apps/docgen/mono.lua delete mode 100644 src/scripts/elua/apps/docgen/stats.lua delete mode 100644 src/scripts/elua/apps/docgen/util.lua delete mode 100644 src/scripts/elua/apps/docgen/writer.lua delete mode 100644 src/scripts/elua/apps/gendoc.lua delete mode 100755 src/scripts/elua/apps/gendoc.sh diff --git a/src/Makefile_Elua.am b/src/Makefile_Elua.am index 069a33c0ef..f172a228b9 100644 --- a/src/Makefile_Elua.am +++ b/src/Makefile_Elua.am @@ -57,21 +57,10 @@ include Makefile_Elua_Helper.am endif eluaapps_files = \ - scripts/elua/apps/lualian.lua \ - scripts/elua/apps/gendoc.lua \ - scripts/elua/apps/gendoc.sh \ - scripts/elua/apps/README-docgen.md + scripts/elua/apps/lualian.lua EXTRA_DIST2 += $(eluaapps_files) -eluadocgen_files = \ - scripts/elua/apps/docgen/doctree.lua \ - scripts/elua/apps/docgen/keyref.lua \ - scripts/elua/apps/docgen/stats.lua \ - scripts/elua/apps/docgen/util.lua \ - scripts/elua/apps/docgen/writer.lua - -EXTRA_DIST2 += $(eluadocgen_files) eluamodules_files = \ scripts/elua/modules/benchmark.lua \ scripts/elua/modules/getopt.lua \ @@ -108,8 +97,6 @@ eluaappsdir = $(datadir)/elua/apps eluaapps_DATA = $(eluaapps_files) eluamodulesdir = $(datadir)/elua/modules eluamodules_DATA = $(eluamodules_files) -eluadocgendir = $(datadir)/elua/apps/docgen -eluadocgen_DATA = $(eluadocgen_files) eluaeinadir = $(eluamodulesdir)/eina eluaeina_DATA = $(eluaeina_files) eluacoredir = $(datadir)/elua/core diff --git a/src/scripts/elua/apps/README-docgen.md b/src/scripts/elua/apps/README-docgen.md deleted file mode 100644 index 9b501ddfc2..0000000000 --- a/src/scripts/elua/apps/README-docgen.md +++ /dev/null @@ -1,9 +0,0 @@ -# docgen - -This is the upcoming documentation generator for EFL. It takes documentation -described in Eo files and turns it into a DokuWiki structure (with possibility -of adapting it to other systems later on). - -Use the supplied build.sh script to generate. By default, it assumes that a -directory called "dokuwiki" is present in the current directory, so symlink -your dokuwiki setup into it (or change the path). diff --git a/src/scripts/elua/apps/docgen/doctree.lua b/src/scripts/elua/apps/docgen/doctree.lua deleted file mode 100644 index 45171ca255..0000000000 --- a/src/scripts/elua/apps/docgen/doctree.lua +++ /dev/null @@ -1,1427 +0,0 @@ -local util = require("util") - -local eolian = require("eolian") - -local keyref = require("docgen.keyref") -local dutil = require("docgen.util") - --- writer has to be loaded late to prevent cycles -local writer - -local M = {} -local eos = eolian:new() - -local get_cache = function(o, nm) - local ret = o[nm] - if not ret then - ret = {} - o[nm] = ret - return ret, false - end - return ret, true -end - -local matches_filter = function(obj) - local ns = obj:nspaces_get() - if #ns and (ns[1] == "efl" or ns[1] == "eina") then - return true - end - - return false -end - -M.Node = util.Object:clone { - scope = { - UNKNOWN = eolian.object_scope.UNKNOWN, - PUBLIC = eolian.object_scope.PUBLIC, - PRIVATE = eolian.object_scope.PRIVATE, - PROTECTED = eolian.object_scope.PROTECTED - }, - - __ctor = function(self, obj) - self._obj = obj - assert(self._obj) - end, - - name_get = function(self) - return self._obj:name_get() - end, - - short_name_get = function(self) - return self._obj:short_name_get() - end, - - namespaces_get = function(self) - return self._obj:namespaces_get():to_array() - end, - - nspaces_get = function(self, root) - local tbl = self:namespaces_get() - -- temporary workaround - if type(tbl) ~= "table" then - tbl = tbl:to_array() - end - for i = 1, #tbl do - tbl[i] = tbl[i]:lower() - end - - tbl[#tbl + 1] = self:short_name_get():lower() - if root ~= nil then - tbl[#tbl + 1] = not not root - end - return tbl - end -} -local Node = M.Node - -local gen_doc_refd = function(str) - if not writer then - writer = require("docgen.writer") - end - if not str then - return nil - end - local pars = eolian.documentation_string_split(str) - for i = 1, #pars do - pars[i] = writer.Buffer():write_par(pars[i]):finish() - end - return table.concat(pars, "\n\n") -end - -local add_since = function(str, since) - if not writer then - writer = require("docgen.writer") - end - if not since then - return str - end - local buf = writer.Buffer() - if not str then - buf:write_i("Since " .. since) - return buf:finish() - end - buf:write_raw(str) - buf:write_nl(2) - buf:write_i("Since " .. since) - return buf:finish() -end - -M.Doc = Node:clone { - -- duplicate ctor to disable assertion - __ctor = function(self, obj) - self._obj = obj - end, - - summary_get = function(self) - if not self._obj then - return nil - end - return self._obj:summary_get() - end, - - description_get = function(self) - if not self._obj then - return nil - end - return self._obj:description_get() - end, - - since_get = function(self) - if not self._obj then - return nil - end - return self._obj:since_get() - end, - - brief_get = function(self, doc2) - if not self._obj and (not doc2 or not doc2._obj) then - return "No description supplied." - end - local doc1, doc2 = self._obj, doc2 and doc2._obj or nil - if not doc1 then - doc1, doc2 = doc2, doc1 - end - return gen_doc_refd(doc1:summary_get()) - end, - - full_get = function(self, doc2, write_since) - if not self._obj and (not doc2 or not doc2._obj) then - return "No description supplied." - end - local doc1, doc2 = self._obj, doc2 and doc2._obj or nil - if not doc1 then - doc1, doc2 = doc2, doc1 - end - local sum1 = doc1:summary_get() - local desc1 = doc1:description_get() - local edoc = "" - local since - if doc2 then - local sum2 = doc2:summary_get() - local desc2 = doc2:description_get() - if not desc2 then - if sum2 then edoc = "\n\n" .. sum2 end - else - edoc = "\n\n" .. sum2 .. "\n\n" .. desc2 - end - if write_since then - since = doc2:since_get() - end - end - if not since and write_since then - since = doc1:since_get() - end - if not desc1 then - return add_since(gen_doc_refd(sum1 .. edoc), since) - end - return add_since(gen_doc_refd(sum1 .. "\n\n" .. desc1 .. edoc), since) - end, - - exists = function(self) - return not not self._obj - end -} - -local revh = {} - -local class_type_str = { - [eolian.class_type.REGULAR] = "class", - [eolian.class_type.ABSTRACT] = "class", - [eolian.class_type.MIXIN] = "mixin", - [eolian.class_type.INTERFACE] = "interface" -} - -M.Class = Node:clone { - -- class types - UNKNOWN = eolian.class_type.UNKNOWN, - REGULAR = eolian.class_type.REGULAR, - ABSTRACT = eolian.class_type.ABSTRACT, - MIXIN = eolian.class_type.MIXIN, - INTERFACE = eolian.class_type.INTERFACE, - - type_get = function(self) - return self._obj:type_get() - end, - - type_str_get = function(self) - return class_type_str[self:type_get()] - end, - - theme_str_get = function(self) - return ({ - [eolian.class_type.REGULAR] = "regular", - [eolian.class_type.ABSTRACT] = "abstract", - [eolian.class_type.MIXIN] = "mixin", - [eolian.class_type.INTERFACE] = "interface" - })[self:type_get()] - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - legacy_prefix_get = function(self) - return self._obj:legacy_prefix_get() - end, - - eo_prefix_get = function(self) - return self._obj:eo_prefix_get() - end, - - inherits_get = function(self) - local ret = self._cache_inhc - if ret then - return ret - end - ret = {} - for cl in self._obj:inherits_get() do - ret[#ret + 1] = M.Class(cl) - end - self._cache_inhc = ret - return ret - end, - - children_get = function(self) - return revh[self:name_get()] or {} - end, - - functions_get = function(self, ft) - local ret = self._cache_funcs - if ret then - return ret - end - ret = {} - self._cache_funcs = ret - for fn in self._obj:functions_get(ft) do - ret[#ret + 1] = M.Function(fn) - end - return ret - end, - - function_by_name_get = function(self, fn, ft) - local fun = self._cache_func - if fun then - return fun - end - fun = M.Function(self._obj:function_by_name_get(fn, ft)) - self._cache_func = fun - return fun - end, - - events_get = function(self) - local ret = {} - for ev in self._obj:events_get() do - ret[#ret + 1] = M.Event(ev) - end - return ret - end, - - implements_get = function(self) - local ret = {} - for impl in self._obj:implements_get() do - ret[#ret + 1] = M.Implement(impl) - end - return ret - end, - - c_get_function_name_get = function(self) - return self._obj:c_get_function_name_get() - end, - - nspaces_get = function(self, root) - return M.Node.nspaces_get(self, root) - end, - - is_same = function(self, other) - return self._obj == other._obj - end, - - -- static getters - - by_name_get = function(name) - local stor = get_cache(M.Class, "_cache_bn") - local ret = stor[name] - if ret then - return ret - end - local v = eos:class_by_name_get(name) - if not v then - return nil - end - ret = M.Class(v) - stor[name] = ret - return ret - end, - - by_file_get = function(name) - local stor = get_cache(M.Class, "_cache_bf") - local ret = stor[name] - if ret then - return ret - end - local v = eos:class_by_file_get(name) - if not v then - return nil - end - ret = M.Class(v) - stor[name] = ret - return ret - end, - - all_get = function() - local ret, had = get_cache(M.Class, "_cache_all") - if not had then - -- FIXME: unit - for cl in eos:classes_get() do - local cls = M.Class(cl) - if matches_filter(cls) then - ret[#ret + 1] = cls - end - end - end - return ret - end -} - -local func_type_str = { - [eolian.function_type.PROPERTY] = "property", - [eolian.function_type.PROP_GET] = "property", - [eolian.function_type.PROP_SET] = "property", - [eolian.function_type.METHOD] = "method" -} - -local ffi = require("ffi") - -M.Function = Node:clone { - -- function types - UNRESOLVED = eolian.function_type.UNRESOLVED, - PROPERTY = eolian.function_type.PROPERTY, - PROP_SET = eolian.function_type.PROP_SET, - PROP_GET = eolian.function_type.PROP_GET, - METHOD = eolian.function_type.METHOD, - FUNCTION_POINTER = eolian.function_type.FUNCTION_POINTER, - - type_get = function(self) - return self._obj:type_get() - end, - - type_str_get = function(self) - return func_type_str[self:type_get()] - end, - - scope_get = function(self, ft) - return self._obj:scope_get(ft) - end, - - full_c_name_get = function(self, ft, legacy) - return self._obj:full_c_name_get(ft, legacy) - end, - - legacy_get = function(self, ft) - return self._obj:legacy_get(ft) - end, - - implement_get = function(self) - return M.Implement(self._obj:implement_get()) - end, - - is_legacy_only = function(self, ft) - return self._obj:is_legacy_only(ft) - end, - - is_class = function(self) - return self._obj:is_class() - end, - - is_beta = function(self) - return self._obj:is_beta() - end, - - is_constructor = function(self, klass) - return self._obj:is_constructor(klass.class) - end, - - is_function_pointer = function(self) - return self._obj:is_function_pointer() - end, - - property_keys_get = function(self, ft) - local ret = {} - for par in self._obj:property_keys_get(ft) do - ret[#ret + 1] = M.Parameter(par) - end - return ret - end, - - property_values_get = function(self, ft) - local ret = {} - for par in self._obj:property_values_get(ft) do - ret[#ret + 1] = M.Parameter(par) - end - return ret - end, - - parameters_get = function(self) - local ret = {} - for par in self._obj:parameters_get() do - ret[#ret + 1] = M.Parameter(par) - end - return ret - end, - - return_type_get = function(self, ft) - local v = self._obj:return_type_get(ft) - if not v then - return nil - end - return M.Type(v) - end, - - return_default_value_get = function(self, ft) - local v = self._obj:return_default_value_get(ft) - if not v then - return nil - end - return M.Expression(v) - end, - - return_doc_get = function(self, ft) - return M.Doc(self._obj:return_documentation_get(ft)) - end, - - return_is_warn_unused = function(self, ft) - return self._obj:return_is_warn_unused(ft) - end, - - is_const = function(self) - return self._obj:is_const() - end, - - nspaces_get = function(self, cl, root) - local tbl = cl:nspaces_get() - tbl[#tbl + 1] = self:type_str_get() - tbl[#tbl + 1] = self:name_get():lower() - if root ~= nil then - tbl[#tbl + 1] = not not root - end - return tbl - end, - - is_same = function(self, other) - return self._obj == other._obj - end, - - id_get = function(self) - return tonumber(ffi.cast("uintptr_t", self._obj)) - end -} - -M.Parameter = Node:clone { - UNKNOWN = eolian.parameter_dir.UNKNOWN, - IN = eolian.parameter_dir.IN, - OUT = eolian.parameter_dir.OUT, - INOUT = eolian.parameter_dir.INOUT, - - direction_get = function(self) - return self._obj:direction_get() - end, - - direction_name_get = function(self) - local dir_to_str = { - [self.IN] = "in", - [self.OUT] = "out", - [self.INOUT] = "inout" - } - return assert(dir_to_str[self:direction_get()], - "unknown parameter direction") - end, - - type_get = function(self) - local v = self._obj:type_get() - if not v then - return nil - end - return M.Type(v) - end, - - default_value_get = function(self) - local v = self._obj:default_value_get() - if not v then - return nil - end - return M.Expression(v) - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - is_nonull = function(self) - return self._obj:is_nonull() - end, - - is_nullable = function(self) - return self._obj:is_nullable() - end, - - is_optional = function(self) - return self._obj:is_optional() - end, - - is_same = function(self, other) - return self._obj == other._obj - end -} - -M.Event = Node:clone { - type_get = function(self) - local v = self._obj:type_get() - if not v then - return nil - end - return M.Type(v) - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - scope_get = function(self) - return self._obj:scope_get() - end, - - c_name_get = function(self) - return self._obj:c_name_get() - end, - - is_beta = function(self) - return self._obj:is_beta() - end, - - is_hot = function(self) - return self._obj:is_hot() - end, - - is_restart = function(self) - return self._obj:is_restart() - end, - - nspaces_get = function(self, cl, root) - local tbl = cl:nspaces_get() - tbl[#tbl + 1] = "event" - tbl[#tbl + 1] = self:name_get():lower():gsub(",", "_") - if root ~= nil then - tbl[#tbl + 1] = not not root - end - return tbl - end -} - -M.StructField = Node:clone { - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - type_get = function(self) - local v = self._obj:type_get() - if not v then - return nil - end - return M.Type(v) - end -} - -M.EnumField = Node:clone { - c_name_get = function(self) - return self._obj:c_name_get() - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - value_get = function(self, force) - local v = self._obj:value_get(force) - if not v then - return nil - end - return M.Expression(v) - end -} - -local wrap_type_attrs = function(tp, str) - if tp:is_const() then - str = "const(" .. str .. ")" - end - -- TODO: implement new ownership system into docs - --if tp:is_own() then - -- str = "own(" .. str .. ")" - --end - local ffunc = tp:free_func_get() - if ffunc then - str = "free(" .. str .. ", " .. ffunc .. ")" - end - if tp:is_ptr() then - str = "ptr(" .. str .. ")" - end - return str -end - -M.Type = Node:clone { - UNKNOWN = eolian.type_type.UNKNOWN, - VOID = eolian.type_type.VOID, - REGULAR = eolian.type_type.REGULAR, - CLASS = eolian.type_type.CLASS, - UNDEFINED = eolian.type_type.UNDEFINED, - - type_get = function(self) - return self._obj:type_get() - end, - - file_get = function(self) - return self._obj:file_get() - end, - - base_type_get = function(self) - local v = self._obj:base_type_get() - if not v then - return nil - end - return M.Type(v) - end, - - next_type_get = function(self) - local v = self._obj:next_type_get() - if not v then - return nil - end - return M.Type(v) - end, - - typedecl_get = function(self) - local v = self._obj:typedecl_get() - if not v then - return nil - end - return M.Typedecl(v) - end, - - aliased_base_get = function(self) - local v = self._obj:aliased_base_get() - if not v then - return nil - end - return M.Type(v) - end, - - class_get = function(self) - return self._obj:class_get() - end, - - is_owned = function(self) - return self._obj:is_owned() - end, - - is_const = function(self) - return self._obj:is_const() - end, - - is_ptr = function(self) - return self._obj:is_ptr() - end, - - c_type_get = function(self) - return self._obj:c_type_get(eolian.c_type_type.DEFAULT) - end, - - free_func_get = function(self) - return self._obj:free_func_get() - end, - - -- utils - - serialize = function(self) - local tpt = self:type_get() - if tpt == self.UNKNOWN then - error("unknown type: " .. self:name_get()) - elseif tpt == self.VOID then - return wrap_type_attrs(self, "void") - elseif tpt == self.UNDEFINED then - return wrap_type_attrs(self, "__undefined_type") - elseif tpt == self.REGULAR or tpt == self.CLASS then - local stp = self:base_type_get() - if stp then - local stypes = {} - while stp do - stypes[#stypes + 1] = stp:serialize() - stp = stp:next_type_get() - end - return wrap_type_attrs(self, self:name_get() .. "<" - .. table.concat(stypes, ", ") .. ">") - end - return wrap_type_attrs(self, self:name_get()) - end - error("unhandled type type: " .. tpt) - end -} - -M.type_cstr_get = function(tp, suffix) - tp = tp or "void" - local ct = (type(tp) == "string") and tp or tp:c_type_get() - if not suffix then - return ct - end - if ct:sub(#ct) == "*" then - return ct .. suffix - else - return ct .. " " .. suffix - end -end - -local add_typedecl_attrs = function(tp, buf) - if tp:is_extern() then - buf[#buf + 1] = "@extern " - end - local ffunc = tp:free_func_get() - if ffunc then - buf[#buf + 1] = "@free(" - buf[#buf + 1] = ffunc - buf[#buf + 1] = ") " - end -end - -M.Typedecl = Node:clone { - UNKNOWN = eolian.typedecl_type.UNKNOWN, - STRUCT = eolian.typedecl_type.STRUCT, - STRUCT_OPAQUE = eolian.typedecl_type.STRUCT_OPAQUE, - ENUM = eolian.typedecl_type.ENUM, - ALIAS = eolian.typedecl_type.ALIAS, - FUNCTION_POINTER = eolian.typedecl_type.FUNCTION_POINTER, - - type_get = function(self) - return self._obj:type_get() - end, - - type_str_get = function(self) - local strs = { - [eolian.typedecl_type.STRUCT] = "struct", - [eolian.typedecl_type.STRUCT_OPAQUE] = "struct", - [eolian.typedecl_type.ENUM] = "enum", - [eolian.typedecl_type.ALIAS] = "alias" - } - return strs[self:type_get()] - end, - - struct_fields_get = function(self) - local ret = {} - for fl in self._obj:struct_fields_get() do - ret[#ret + 1] = M.StructField(fl) - end - return ret - end, - - struct_field_get = function(self, name) - local v = self._obj:struct_field_get(name) - if not v then - return nil - end - return M.StructField(v) - end, - - enum_fields_get = function(self) - local ret = {} - for fl in self._obj:enum_fields_get() do - ret[#ret + 1] = M.EnumField(fl) - end - return ret - end, - - enum_field_get = function(self, name) - local v = self._obj:enum_field_get(name) - if not v then - return nil - end - return M.EnumField(v) - end, - - enum_legacy_prefix_get = function(self) - return self._obj:enum_legacy_prefix_get() - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - file_get = function(self) - return self._obj:file_get() - end, - - base_type_get = function(self) - local v = self._obj:base_type_get() - if not v then - return nil - end - return M.Type(v) - end, - - aliased_base_get = function(self) - local v = self._obj:aliased_base_get() - if not v then - return nil - end - return M.Type(v) - end, - - is_extern = function(self) - return self._obj:is_extern() - end, - - c_type_get = function(self) - return self._obj:c_type_get() - end, - - free_func_get = function(self) - return self._obj:free_func_get() - end, - - function_pointer_get = function(self) - local v = self._obj:function_pointer_get() - if not v then - return nil - end - return M.Function(v) - end, - - nspaces_get = function(self, root) - return M.Node.nspaces_get(self, root) - end, - - -- static getters - - all_aliases_get = function() - local ret = {} - for tp in eos:aliases_get() do - local tpo = M.Typedecl(tp) - if matches_filter(tpo) then - ret[#ret + 1] = tpo - end - end - return ret - end, - - all_structs_get = function() - local ret = {} - for tp in eos:structs_get() do - local tpo = M.Typedecl(tp) - if matches_filter(tpo) then - ret[#ret + 1] = tpo - end - end - return ret - end, - - all_enums_get = function() - local ret = {} - for tp in eos:enums_get() do - local tpo = M.Typedecl(tp) - local tpn = tpo:nspaces_get() - if matches_filter(tpo) then - ret[#ret + 1] = tpo - end - end - return ret - end, - - aliases_by_file_get = function(fn) - local ret = {} - for tp in eos:aliases_by_file_get(fn) do - ret[#ret + 1] = M.Typedecl(tp) - end - return ret - end, - - structs_by_file_get = function(fn) - local ret = {} - for tp in eos:struts_by_file_get(fn) do - ret[#ret + 1] = M.Typedecl(tp) - end - return ret - end, - - enums_by_file_get = function(fn) - local ret = {} - for tp in eeos:enums_by_file_get(fn) do - ret[#ret + 1] = M.Typedecl(tp) - end - return ret - end, - - alias_by_name_get = function(tn) - local v = eos:alias_by_name_get(tn) - if not v then - return nil - end - return M.Typedecl(v) - end, - - struct_by_name_get = function(tn) - local v = eos:struct_by_name_get(tn) - if not v then - return nil - end - return M.Typedecl(v) - end, - - enum_by_name_get = function(tn) - local v = eos:enum_by_name_get(tn) - if not v then - return nil - end - return M.Typedecl(v) - end, - - -- utils - - serialize = function(self) - local tpt = self:type_get() - if tpt == self.UNKNOWN then - error("unknown typedecl: " .. self:name_get()) - elseif tpt == self.STRUCT or - tpt == self.STRUCT_OPAQUE then - local buf = { "struct " } - add_typedecl_attrs(self, buf) - buf[#buf + 1] = self:name_get() - if tpt == self.STRUCT_OPAQUE then - buf[#buf + 1] = ";" - return table.concat(buf) - end - local fields = self:struct_fields_get() - if #fields == 0 then - buf[#buf + 1] = " {}" - return table.concat(buf) - end - buf[#buf + 1] = " {\n" - for i, fld in ipairs(fields) do - buf[#buf + 1] = " " - buf[#buf + 1] = fld:name_get() - buf[#buf + 1] = ": " - buf[#buf + 1] = fld:type_get():serialize() - buf[#buf + 1] = ";\n" - end - buf[#buf + 1] = "}" - return table.concat(buf) - elseif tpt == self.ENUM then - local buf = { "enum " } - add_typedecl_attrs(self, buf) - buf[#buf + 1] = self:name_get() - local fields = self:enum_fields_get() - if #fields == 0 then - buf[#buf + 1] = " {}" - return table.concat(buf) - end - buf[#buf + 1] = " {\n" - for i, fld in ipairs(fields) do - buf[#buf + 1] = " " - buf[#buf + 1] = fld:name_get() - local val = fld:value_get() - if val then - buf[#buf + 1] = ": " - buf[#buf + 1] = val:serialize() - end - if i == #fields then - buf[#buf + 1] = "\n" - else - buf[#buf + 1] = ",\n" - end - end - buf[#buf + 1] = "}" - return table.concat(buf) - elseif tpt == self.ALIAS then - local buf = { "type " } - add_typedecl_attrs(self, buf) - buf[#buf + 1] = self:name_get() - buf[#buf + 1] = ": " - buf[#buf + 1] = self:base_type_get():serialize() - buf[#buf + 1] = ";" - return table.concat(buf) - elseif tpt == self.FUNCTION_POINTER then - return "TODO" - end - error("unhandled typedecl type: " .. tpt) - end, - - serialize_c = function(self, ns) - local tpt = self:type_get() - if tpt == self.UNKNOWN then - error("unknown typedecl: " .. self:name_get()) - elseif tpt == self.STRUCT or - tpt == self.STRUCT_OPAQUE then - local buf = { "typedef struct " } - local fulln = self:name_get():gsub("%.", "_"); - keyref.add(fulln, ns, "c") - buf[#buf + 1] = "_" .. fulln; - if tpt == self.STRUCT_OPAQUE then - buf[#buf + 1] = " " .. fulln .. ";" - return table.concat(buf) - end - local fields = self:struct_fields_get() - if #fields == 0 then - buf[#buf + 1] = " {} " .. fulln .. ";" - return table.concat(buf) - end - buf[#buf + 1] = " {\n" - for i, fld in ipairs(fields) do - buf[#buf + 1] = " " - buf[#buf + 1] = M.type_cstr_get(fld:type_get(), fld:name_get()) - buf[#buf + 1] = ";\n" - end - buf[#buf + 1] = "} " .. fulln .. ";" - return table.concat(buf) - elseif tpt == self.ENUM then - local buf = { "typedef enum" } - local fulln = self:name_get():gsub("%.", "_"); - keyref.add(fulln, ns, "c") - local fields = self:enum_fields_get() - if #fields == 0 then - buf[#buf + 1] = " {} " .. fulln .. ";" - return table.concat(buf) - end - buf[#buf + 1] = " {\n" - for i, fld in ipairs(fields) do - buf[#buf + 1] = " " - local cn = fld:c_name_get() - buf[#buf + 1] = cn - keyref.add(cn, ns, "c") - local val = fld:value_get() - if val then - buf[#buf + 1] = " = " - local ev = val:eval_enum() - local lit = ev:to_literal() - buf[#buf + 1] = lit - local ser = val:serialize() - if ser and ser ~= lit then - buf[#buf + 1] = " /* " .. ser .. " */" - end - end - if i == #fields then - buf[#buf + 1] = "\n" - else - buf[#buf + 1] = ",\n" - end - end - buf[#buf + 1] = "} " .. fulln .. ";" - return table.concat(buf) - elseif tpt == self.ALIAS then - local fulln = self:name_get():gsub("%.", "_"); - keyref.add(fulln, ns, "c") - return "typedef " - .. M.type_cstr_get(self:base_type_get(), fulln) .. ";" - elseif tpt == self.FUNCTION_POINTER then - return "TODO" - end - error("unhandled typedecl type: " .. tpt) - end -} - -M.Variable = Node:clone { - UNKNOWN = eolian.variable_type.UNKNOWN, - CONSTANT = eolian.variable_type.CONSTANT, - GLOBAL = eolian.variable_type.GLOBAL, - - type_get = function(self) - return self._obj:type_get() - end, - - type_str_get = function(self) - local strs = { - [eolian.variable_type.CONSTANT] = "constant", - [eolian.variable_type.GLOBAL] = "global" - } - return strs[self:type_get()] - end, - - doc_get = function(self) - return M.Doc(self._obj:documentation_get()) - end, - - file_get = function(self) - return self._obj:file_get() - end, - - base_type_get = function(self) - local v = self._obj:base_type_get() - if not v then - return nil - end - return M.Type(v) - end, - - value_get = function(self) - local v = self._obj:value_get() - if not v then - return nil - end - return M.Expression(v) - end, - - is_extern = function(self) - return self._obj:is_extern() - end, - - nspaces_get = function(self, root) - return M.Node.nspaces_get(self, root) - end, - - serialize = function(self) - local buf = {} - if self:type_get() == self.GLOBAL then - buf[#buf + 1] = "var " - else - buf[#buf + 1] = "const " - end - if self:is_extern() then - buf[#buf + 1] = "@extern " - end - buf[#buf + 1] = self:name_get() - buf[#buf + 1] = ": " - buf[#buf + 1] = self:base_type_get():serialize() - local val = self:value_get() - if val then - buf[#buf + 1] = " = " - buf[#buf + 1] = val:serialize() - end - buf[#buf + 1] = ";" - return table.concat(buf) - end, - - serialize_c = function(self, ns) - local buf = {} - local bt = self:base_type_get() - local fulln = self:name_get():gsub("%.", "_"):upper() - keyref.add(fulln, ns, "c") - if self:type_get() == self.GLOBAL then - local ts = bt:c_type_get() - buf[#buf + 1] = ts - if ts:sub(#ts) ~= "*" then - buf[#buf + 1] = " " - end - buf[#buf + 1] = fulln - local val = self:value_get() - if val then - buf[#buf + 1] = " = " - local vt = val:eval_type(bt) - local lv = vt:to_literal() - local sv = val:serialize() - buf[#buf + 1] = lv - if lv ~= sv then - buf[#buf + 1] = "/* " .. sv .. " */" - end - end - buf[#buf + 1] = ";" - else - buf[#buf + 1] = "#define " - buf[#buf + 1] = fulln - buf[#buf + 1] = " " - local val = self:value_get() - local vt = val:eval_type(bt) - local lv = vt:to_literal() - local sv = val:serialize() - buf[#buf + 1] = lv - if lv ~= sv then - buf[#buf + 1] = "/* " .. sv .. " */" - end - end - return table.concat(buf) - end, - - -- static getters - - all_globals_get = function() - local ret = {} - for v in eos:globals_get() do - ret[#ret + 1] = M.Variable(v) - end - return ret - end, - - all_constants_get = function() - local ret = {} - for v in eos:constants_get() do - ret[#ret + 1] = M.Variable(v) - end - return ret - end, - - globals_by_file_get = function(fn) - local ret = {} - for v in eos:globals_by_file_get(fn) do - ret[#ret + 1] = M.Variable(v) - end - return ret - end, - - constants_by_file_get = function(fn) - local ret = {} - for v in eos:constants_by_file_get(fn) do - ret[#ret + 1] = M.Variable(v) - end - return ret - end, - - global_by_name_get = function(vn) - local v = eos:global_by_name_get(vn) - if not v then - return nil - end - return M.Variable(v) - end, - - constant_by_name_get = function(vn) - local v = eos:constant_by_name_get(vn) - if not v then - return nil - end - return M.Variable(v) - end -} - -M.Expression = Node:clone { - eval_enum = function(self) - return self._obj:eval(eolian.expression_mask.INT) - end, - - eval_type = function(self, tp) - return self._obj:eval_type(tp.type) - end, - - serialize = function(self) - return self._obj:serialize() - end -} - -M.Implement = Node:clone { - class_get = function(self) - local ccl = self._cache_cl - if ccl then - return ccl - end - -- so that we don't re-instantiate, it gets cached over there too - ccl = M.Class.by_name_get(self._obj:class_get():name_get()) - self._cache_cl = ccl - return ccl - end, - - function_get = function(self) - local func, tp = self._cache_func, self._cache_tp - if func then - return func, tp - end - func, tp = self._obj:function_get() - func = M.Function(func) - self._cache_func, self._cache_tp = func, tp - return func, tp - end, - - doc_get = function(self, ftype, inh) - return M.Doc(self._obj:documentation_get(ftype)) - end, - - fallback_doc_get = function(self, inh) - local ig, is = self:is_prop_get(), self:is_prop_set() - if ig and not is then - return self:doc_get(M.Function.PROP_GET, inh) - elseif is and not ig then - return self:doc_get(M.Function.PROP_SET, inh) - end - return nil - end, - - is_auto = function(self, ftype) - return self._obj:is_auto(ftype) - end, - - is_empty = function(self, ftype) - return self._obj:is_empty(ftype) - end, - - is_pure_virtual = function(self, ftype) - return self._obj:is_pure_virtual(ftype) - end, - - is_prop_get = function(self) - return self._obj:is_prop_get() - end, - - is_prop_set = function(self) - return self._obj:is_prop_set() - end, - - is_overridden = function(self, cl) - return cl.class ~= self._obj:class_get() - end -} - -M.DocTokenizer = util.Object:clone { - UNKNOWN = eolian.doc_token_type.UNKNOWN, - TEXT = eolian.doc_token_type.TEXT, - REF = eolian.doc_token_type.REF, - MARK_NOTE = eolian.doc_token_type.MARK_NOTE, - MARK_WARNING = eolian.doc_token_type.MARK_WARNING, - MARK_REMARK = eolian.doc_token_type.MARK_REMARK, - MARK_TODO = eolian.doc_token_type.MARK_TODO, - MARKUP_MONOSPACE = eolian.doc_token_type.MARKUP_MONOSPACE, - - __ctor = function(self, str) - self.tok = eolian.doc_token_init() - self.str = str - assert(self.str) - assert(self.tok) - end, - - tokenize = function(self) - self.str = eolian.documentation_tokenize(self.str, self.tok) - return not not self.str - end, - - text_get = function(self) - return self.tok:text_get() - end, - - type_get = function(self) - return self.tok:type_get() - end, - - ref_resolve = function(self, root) - -- FIXME: unit - local tp, d1, d2 = self.tok:ref_resolve(eos) - local reft = eolian.object_type - local ret = {} - if tp == reft.CLASS or tp == reft.FUNCTION or tp == reft.EVENT then - if not class_type_str[d1:type_get()] then - error("unknown class type for class '" - .. d1:name_get() .. "'") - end - elseif tp == reft.TYPEDECL then - elseif tp == reft.ENUM_FIELD or tp == reft.STRUCT_FIELD then - -- TODO: point to field - elseif tp == reft.VARIABLE then - else - error("invalid reference '" .. self:text_get() .. "'") - end - for tok in d1:name_get():gmatch("[^%.]+") do - ret[#ret + 1] = tok:lower() - end - if tp == reft.FUNCTION then - ret[#ret + 1] = func_type_str[d2:type_get()] - ret[#ret + 1] = d2:name_get():lower() - elseif tp == reft.EVENT then - ret[#ret + 1] = "event" - ret[#ret + 1] = d2:name_get():lower() - end - if root ~= nil then - ret[#ret + 1] = not not root - end - return ret - end -} - -M.scan_directory = function(dir) - if not dir then - if not eos:system_directory_add() then - error("failed scanning system directory") - end - return - end - if not eos:directory_add(dir) then - error("failed scanning directory: " .. dir) - end -end - -M.parse = function(st) - if not eos:all_eot_files_parse() then - error("failed parsing eo type files") - end - if st and st:match("%.") then - if not eos:file_parse(st:gsub("%.", "_"):lower() .. ".eo") then - error("failed parsing eo file") - end - else - if not eos:all_eo_files_parse() then - error("failed parsing eo files") - end - end - -- build reverse inheritance hierarchy - for cl in eos:classes_get() do - local cln = cl:name_get() - for icl in cl:inherits_get() do - local t = revh[icl] - if not t then - t = {} - revh[icl] = t - end - t[#t + 1] = M.Class.by_name_get(cl:name_get()) - end - end -end - -return M diff --git a/src/scripts/elua/apps/docgen/keyref.lua b/src/scripts/elua/apps/docgen/keyref.lua deleted file mode 100644 index 56311d9742..0000000000 --- a/src/scripts/elua/apps/docgen/keyref.lua +++ /dev/null @@ -1,41 +0,0 @@ -local M = {} - -local key_refs = {} - -M.add = function(key, link, lang) - local rfs = key_refs[lang] - if not rfs then - key_refs[lang] = {} - rfs = key_refs[lang] - end - rfs[key] = link -end - -M.build = function() - local writer = require("docgen.writer") - local dutil = require("docgen.util") - for lang, rfs in pairs(key_refs) do - local f = writer.Writer({ "ref", lang, "keyword-list" }) - local arr = {} - for refn, v in pairs(rfs) do - arr[#arr + 1] = refn - local rf = writer.Writer({ "ref", lang, "key", refn }) - v[#v + 1] = true - rf:write_include(rf.INCLUDE_PAGE, v) - rf:finish() - end - table.sort(arr) - f:write_raw(table.concat(arr, "\n")) - f:write_nl() - f:finish() - local lf = writer.Writer({ "ref", lang, "keyword-link" }) - lf:write_raw("/", dutil.path_join( - dutil.nspace_to_path(dutil.get_root_ns()), - "ref", lang, "key", "{FNAME}" - )) - lf:write_nl() - lf:finish() - end -end - -return M diff --git a/src/scripts/elua/apps/docgen/mono.lua b/src/scripts/elua/apps/docgen/mono.lua deleted file mode 100644 index dbe98de171..0000000000 --- a/src/scripts/elua/apps/docgen/mono.lua +++ /dev/null @@ -1,614 +0,0 @@ - -local writer = require("docgen.writer") -local dtree = require("docgen.doctree") - -local M = {} - -local propt_to_type = { - [dtree.Function.PROPERTY] = "(get, set)", - [dtree.Function.PROP_GET] = "(get)", - [dtree.Function.PROP_SET] = "(set)", -} - -local verbs = { - "add", - "get", - "is", - "del", - "thaw", - "freeze", - "save", - "wait", - "eject", - "raise", - "lower", - "load", - "dup", - "reset", - "unload", - "close", - "set", - "interpolate", - "has", - "grab", - "check", - "find", - "ungrab", - "unset", - "clear", - "pop", - "new", - "peek", - "push", - "update", - "show", - "move", - "hide", - "calculate", - "resize", - "attach", - "pack", - "unpack", - "emit", - "call", - "append" -} - -local not_verbs = { - "below", - "above", - "name", - "unfreezable", - "value", - "r", - "g", - "b", - "a", - "finalize", - "destructor", - "to", - "circle", - "rect", - "path", - "commands", - "type", - "colorspace", - "op", - "type", - "properties", - "status", - "status", - "relative", - "ptr", - "pair", - "pos", - "end" -} - -local get_class_name = function(cls) - local words = {} - local klass = cls:name_get() - for word in string.gmatch(klass, "%a+") do - words[#words+1] = word - end - for i = 1, #words -1 do - words[i] = string.lower(words[i]) - end - return table.concat(words, '.') -end - -local get_mono_type -get_mono_type = function(tp) - if not tp then - return "void " - end - - tpt = tp:type_get() - tpdecl = tp:typedecl_get() - - if tpt == tp.REGULAR then - if tp:name_get() == "string" then - return "System.String" - elseif tp:name_get() == "list" then - ntp = tp:base_type_get() - --assert(btp ~= nil) - --ntp = btp:next_type_get() - return "eina.List<" .. get_mono_type(ntp) .. ">" - elseif tpdecl then - --print("typedecl type is ", tp:name_get()) - tpt = tpdecl:type_get() - return get_class_name(tp) --tp:name_get() - else - --print("regular type is ", tp:name_get()) - return tp:name_get() - end - elseif tpt == tp.CLASS then - return get_class_name(tp) - else - return "unknown" - end -end - - -local is_verb = function(word) - for i = 1, #verbs do - if verbs[i] == word then - return true - end - end - return false -end - -local mono_method_name_get = function(f, ftype) - local cn = f:name_get(ftype) - - local words = {} - - for word in string.gmatch(cn, "%a+") do - words[#words+1] = word - end - - if #words > 1 and is_verb(words[#words]) then - local tmp = words[#words] - words[#words] = words[1] - words[1] = tmp - end - - for i = 1, #words do - words[i] = words[i]:gsub("^%l", string.upper) - end - - if ftype == f.PROP_GET then - table.insert(words, 1, "Get") - elseif ftype == f.PROP_SET then - table.insert(words, 1, "Set") - end - - return table.concat(words) -end - -local gen_mono_param = function(par, out) - local part = par:type_get() - out = out or (par:direction_get() == par.OUT) - if out then - out = "out " - else - out = "" - end - - return out .. get_mono_type(par:type_get()) .. ' ' .. par:name_get() - --local tstr = part:c_type_get() - --return out .. dtree.type_cstr_get(tstr, par:name_get()) -end - -local get_func_mono_sig_part = function(cn, tp) - return get_mono_type(tp) .. " " .. cn -end - -local find_parent_impl -find_parent_impl = function(fulln, cl) - for i, pcl in ipairs(cl:inherits_get()) do - for j, impl in ipairs(pcl:implements_get()) do - if impl:name_get() == fulln then - --if get_class_name(impl) == fulln then - return impl, pcl - end - end - local pimpl, pcl = find_parent_impl(fulln, pcl) - if pimpl then - return pimpl, pcl - end - end - return nil, cl -end - -local find_parent_briefdoc -find_parent_briefdoc = function(fulln, cl) - local pimpl, pcl = find_parent_impl(fulln, cl) - if not pimpl then - return dtree.Doc():brief_get() - end - local pdoc = pimpl:doc_get(dtree.Function.METHOD, true) - local pdocf = pimpl:fallback_doc_get(true) - if not pdoc:exists() and (not pdocf or not pdocf:exists()) then - return find_parent_briefdoc(fulln, pcl) - end - return pdoc:brief_get(pdocf) -end - - -local write_description = function(f, impl, func, cl) - local over = impl:is_overridden(cl) - local bdoc - - local doc = impl:doc_get(func.METHOD, true) - local docf = impl:fallback_doc_get(true) - if over and (not doc:exists() and (not docf or not docf:exists())) then - bdoc = find_parent_briefdoc(impl:name_get(), cl) - else - bdoc = doc:brief_get(docf) - end - if bdoc ~= "No description supplied." then - f:write_raw(bdoc) - end -end - -local write_scope = function(f, func) - local ftt = { - [func.scope.PROTECTED] = "protected", - [func.scope.PRIVATE] = "private" - } - if func:is_class() then - f:write_raw(" ") - f:write_m("class") - end - if func:type_get() == func.PROPERTY then - local ft1, ft2 = ftt[func:scope_get(func.PROP_GET)], - ftt[func:scope_get(func.PROP_SET)] - if ft1 and ft1 == ft2 then - f:write_raw(" ") - f:write_m(ft1) - elseif ft1 or ft2 then - local s = "" - if ft1 then - s = s .. ft1 .. " get" .. (ft2 and ", " or "") - end - if ft2 then - s = s .. ft2 .. " set" - end - f:write_raw(" ") - f:write_m(s) - end - else - local ft = ftt[func:scope_get(func:type_get())] - if ft then - f:write_raw(" ") - f:write_m(ft) - end - end -end - -local write_function = function(f, func, cl) - local llbuf = writer.Buffer() - llbuf:write_link(func:nspaces_get(cl, true), func:name_get()) - f:write_b(llbuf:finish()) - - local pt = propt_to_type[func:type_get()] - if pt then - f:write_raw(" ") - local llbuf = writer.Buffer() - llbuf:write_b(pt) - f:write_i(llbuf:finish()) - end -end - -local gen_func_mono_sig = function(f, ftype) - ftype = ftype or f.METHOD - assert(ftype ~= f.PROPERTY) - - local cn = mono_method_name_get(f, ftype) - local rtype = f:return_type_get(ftype) - local prefix = "" - local suffix = "" - - if f:is_class() then - prefix = "static " - elseif f:is_const() or ftype == f.PROP_GET then - suffix = " const" - end - - if f:type_get() == f.METHOD then - local pars = f:parameters_get() - local cnrt = get_func_mono_sig_part(cn, rtype) - for i = 1, #pars do - pars[i] = gen_mono_param(pars[i]) - end - return prefix .. cnrt .. "(" .. table.concat(pars, ", ") .. ")" .. suffix .. ";" - end - - local keys = f:property_keys_get(ftype) - local vals = f:property_values_get(ftype) - - if ftype == f.PROP_SET then - local cnrt = get_func_mono_sig_part(cn, rtype) - local pars = {} - for i, par in ipairs(keys) do - pars[#pars + 1] = gen_mono_param(par) - end - for i, par in ipairs(vals) do - pars[#pars + 1] = gen_mono_param(par) - end - return cnrt .. "(" .. table.concat(pars, ", ") .. ");" - end - - -- getters - local cnrt - if not rtype then - if #vals == 1 then - cnrt = get_func_mono_sig_part(cn, vals[1]:type_get()) - table.remove(vals, 1) - else - cnrt = get_func_mono_sig_part(cn) - end - else - cnrt = get_func_mono_sig_part(cn, rtype) - end - local pars = {} - for i, par in ipairs(keys) do - pars[#pars + 1] = gen_mono_param(par) - end - for i, par in ipairs(vals) do - --print('parameter is value for get, so out') - pars[#pars + 1] = gen_mono_param(par, true) - end - - return cnrt .. "(" .. table.concat(pars, ", ") .. ");" -end - -local build_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = {} - for i, implt in ipairs(tbl) do - local lbuf = writer.Buffer() - - local cl, impl = unpack(implt) - local func = impl:function_get() - - local wt = {} - wt[0] = cl - wt[1] = func - wt[2] = impl - - nt[#nt + 1] = wt - end - - local get_best_scope = function(f) - local ft = f:type_get() - if ft == f.PROPERTY then - local fs1, fs2 = f:scope_get(f.PROP_GET), f:scope_get(f.PROP_SET) - if fs1 == f.scope.PUBLIC or fs2 == f.scope.PUBLIC then - return f.scope.PUBLIC - elseif fs1 == f.scope.PROTECTED or fs2 == f.scope.PROTECTED then - return f.scope.PROTECTED - else - return f.scope.PRIVATE - end - else - return f:scope_get(ft) - end - end - table.sort(nt, function(v1, v2) - local cl1, cl2 = v1[0], v2[0] - if cl1 ~= cl2 then - return cl1:name_get() < cl2:name_get() - end - - local f1, f2 = v1[1], v2[1] - local f1s, f2s = get_best_scope(f1), get_best_scope(f2) - if f1s ~= f2s then - if f1s ~= f1.scope.PROTECED then - -- public funcs go first, private funcs go last - return f1s == f1.scope.PUBLIC - else - -- protected funcs go second - return f2s == f2.scope.PRIVATE - end - end - return f1:name_get() < f2:name_get() - end) - - return nt -end - -local find_callables -find_callables = function(cl, omeths, events, written) - for i, pcl in ipairs(cl:inherits_get()) do - for j, impl in ipairs(pcl:implements_get()) do - local func = impl:function_get() - local fid = func:id_get() - if not written[fid] then - omeths[#omeths + 1] = { pcl, impl } - written[fid] = true - end - end - for i, ev in ipairs(pcl:events_get()) do - local evid = ev:name_get() - if not written[evid] then - events[#events + 1] = { pcl, ev } - written[evid] = true - end - end - find_callables(pcl, omeths, events, written) - end -end - -M.build_inherits = function(cl, t, lvl) - t = t or {} - lvl = lvl or 0 - local lbuf = writer.Buffer() - if lvl > 0 then - local cln = cl:nspaces_get(true) - cln[#cln] = nil - cln[#cln] = cln[#cln] .. "_mono" - cln = ":" .. 'develop:api' .. ":" - .. table.concat(cln, ":") - lbuf:write_raw("[[", cln, "|", get_class_name(cl), "]]") - --lbuf:write_link(cl:nspaces_get(true), cl:name_get()) - lbuf:write_raw(" ") - lbuf:write_i("(" .. cl:type_str_get() .. ")") - - t[#t + 1] = { lvl - 1, lbuf:finish() } - end - - for i, acl in ipairs(cl:inherits_get()) do - M.build_inherits(acl, t, lvl + 1) - end - return t -end - -M.build_inherit_summary = function(cl, buf) - buf = buf or writer.Buffer() - buf:write_raw(" => ") - - local cln = cl:nspaces_get(true) - cln[#cln] = nil - cln[#cln] = cln[#cln] .. "_mono" - cln = ":" .. 'develop:api' .. ":" - .. table.concat(cln, ":") - buf:write_raw("[[", cln, "|", get_class_name(cl), "]]") - buf:write_raw(" ") - buf:write_i("(" .. cl:type_str_get() .. ")") - - local inherits = cl:inherits_get() - if #inherits ~= 0 then - M.build_inherit_summary(inherits[1], buf) - end - return buf -end - -M.write_inherit_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_functable(t, tcl, tbl) - - local prevcl = tcl - for i, wt in ipairs(nt) do - local cl = wt[0] - local func = wt[1] - local impl = wt[2] - - local ocl = impl:class_get() - local func = impl:function_get() - - -- class grouping for inheritance - if cl ~= prevcl then - prevcl = cl - f:write_raw("^ ") - f:write_link(cl:nspaces_get(true), cl:name_get()) - f:write_raw(" ^^^") - f:write_nl() - end - - -- scope - f:write_raw("| ") - write_scope(f, func) - f:write_raw(" | ") - -- function - write_function(f, func, cl) - f:write_raw(" | ") - -- description - write_description(f, impl, func, cl) - f:write_raw(" |") - f:write_nl() - end - f:write_nl() -end - -M.write_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_functable(t, tcl, tbl) - - local wrote = false - for i, wt in ipairs(nt) do - local cl = wt[0] - local func = wt[1] - local impl = wt[2] - - local ocl = impl:class_get() - local func = impl:function_get() - local over = impl:is_overridden(cl) - - -- function - write_function(f, func, cl) - -- scope - write_scope(f, func) - - -- overrides - if over then - -- TODO: possibly also mention which part of a property was - -- overridden and where, get/set override point might differ! - -- but we get latest doc every time so it's ok for now - local llbuf = writer.Buffer() - llbuf:write_raw(" [Overridden from ") - llbuf:write_link(ocl:nspaces_get(true), ocl:name_get()) - llbuf:write_raw("]") - f:write_i(llbuf:finish()) - end - - -- description - f:write_br(true) - f:write_raw("> ") - write_description(f, impl, func, cl) - - -- code snippets - f:write_nl() - local codes = {} - if func:type_get() ~= dtree.Function.PROPERTY then - codes[#codes + 1] = gen_func_mono_sig(func, func:type_get()) - else - codes[#codes + 1] = gen_func_mono_sig(func, dtree.Function.PROP_GET) - codes[#codes + 1] = gen_func_mono_sig(func, dtree.Function.PROP_SET) - end - f:write_code(table.concat(codes, "\n"), "c") - f:write_br(true) - end - f:write_nl() -end - -M.build_class = function(cl) - local cln = cl:nspaces_get() - local fulln = cl:name_get() - --table.insert(cln, "mono") - cln[#cln] = cln[#cln] .. "_mono" - --printgen("Generating (MONO) class: " .. fulln .. " in ns ", unpack(cln)) - local f = writer.Writer(cln, fulln .. " (mono)") - f:write_h(cl:name_get() .. " (" .. cl:type_str_get() .. ")", 1) - - f:write_h("Description", 2) - f:write_raw(cl:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(cln, "description") - f:write_nl() - - local inherits = cl:inherits_get() - if #inherits ~= 0 then - f:write_h("Inheritance", 2) - - f:write_raw(M.build_inherit_summary(inherits[1]):finish()) - f:write_nl() - - f:write_folded("Full hierarchy", function() - f:write_list(M.build_inherits(cl)) - end) - f:write_nl() - end - - local written = {} - local ievs = {} - local meths, omeths = {}, {} - for i, impl in ipairs(cl:implements_get()) do - local func = impl:function_get() - written[func:id_get()] = true - meths[#meths + 1] = { cl, impl } - end - find_callables(cl, omeths, ievs, written) - - f:write_h("Members", 2) - M.write_functable(f, cl, meths, true) - if #omeths ~= 0 then - f:write_h("Inherited", 3) - end - M.write_inherit_functable(f, cl, omeths, false) - - f:finish() -end - -return M - - diff --git a/src/scripts/elua/apps/docgen/stats.lua b/src/scripts/elua/apps/docgen/stats.lua deleted file mode 100644 index 9659f86dcd..0000000000 --- a/src/scripts/elua/apps/docgen/stats.lua +++ /dev/null @@ -1,274 +0,0 @@ -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 diff --git a/src/scripts/elua/apps/docgen/util.lua b/src/scripts/elua/apps/docgen/util.lua deleted file mode 100644 index 65968ac3e7..0000000000 --- a/src/scripts/elua/apps/docgen/util.lua +++ /dev/null @@ -1,50 +0,0 @@ -local cutil = require("cutil") -local ffi = require("ffi") - -local M = {} - -local doc_root, root_ns - -local path_sep, rep_sep = "/", "\\" -if ffi.os == "Windows" then - path_sep, rep_sep = rep_sep, path_sep -end - -M.path_join = function(...) - return (table.concat({ ... }, path_sep):gsub(rep_sep, path_sep)) -end - -M.path_to_nspace = function(p) - return p:gsub(rep_sep, ":"):gsub(path_sep, ":"):lower() -end - -M.nspace_to_path = function(ns) - return ns:gsub(":", path_sep):gsub(rep_sep, path_sep):lower() -end - -M.make_page = function(path, ext) - return M.path_join(doc_root, path .. "." .. ext) -end - -M.get_root_ns = function() - return root_ns -end - -M.mkdir_r = function(dirn) - assert(cutil.file_mkpath(M.path_join(doc_root, dirn))) -end - -M.mkdir_p = function(path) - M.mkdir_r(path:match("(.+)" .. path_sep .. "([^" .. path_sep .. "]+)")) -end - -M.rm_root = function() - cutil.file_rmrf(doc_root) -end - -M.init = function(root, rns) - doc_root = root:gsub(rep_sep, path_sep) - root_ns = rns -end - -return M diff --git a/src/scripts/elua/apps/docgen/writer.lua b/src/scripts/elua/apps/docgen/writer.lua deleted file mode 100644 index 2aeadf8da7..0000000000 --- a/src/scripts/elua/apps/docgen/writer.lua +++ /dev/null @@ -1,397 +0,0 @@ -local util = require("util") - -local dutil = require("docgen.util") -local dtree = require("docgen.doctree") - -local M = {} - -local root_nspace, features - -M.has_feature = function(fname) - if not features then - return false - end - return not not features[fname] -end - -local allowed_incflags = { - noheader = { "noheader", "showheader" }, - firstseconly = { "firstseconly", "fullpage" }, - readmore = { "readmore", "noreadmore" }, - footer = { "footer", "nofooter" }, - link = { "link", "nolink" }, - permalink = { "permalink", "nopermalink" }, - date = { "date", "nodate" }, - mdate = { "mdate", "nomdate" }, - user = { "user", "nouser" }, - comments = { "comments", "nocomments" }, - linkbacks = { "linkbacks", "nolinkbacks" }, - tags = { "tags", "notags" }, - editbutton = { "editbtn", "noeditbtn" }, - redirect = { "redirect", "noredirect" }, - indent = { "indent", "noindent" }, - linkonly = { "linkonly", "nolinkonly" }, - title = { "title", "notitle" }, - pageexists = { "pageexists", "nopageexists" }, - parlink = { "parlink", "noparlink" }, - order = { { "id", "title", "created", "modified", "indexmenu", "custom" } }, - rsort = { "rsort", "sort" }, - depth = 0, - inline = true, - beforeeach = "", - aftereach = "" -} - -local writers = {} - -local Buffer = { - __ctor = function(self) - self.buf = {} - end, - - write_raw = function(self, ...) - for i, v in ipairs({ ... }) do - self.buf[#self.buf + 1] = v - end - return self - end, - - finish = function(self) - self.result = table.concat(self.buf) - self.buf = {} - return self.result - end -} - -local write_include = function(self, tp, name, flags) - local it_to_tp = { - [self.INCLUDE_PAGE] = "page", - [self.INCLUDE_SECTION] = "section", - [self.INCLUDE_NAMESPACE] = "namespace", - [self.INCLUDE_TAG] = "tagtopic" - } - if type(name) == "table" then - if name[#name] == true then - name[#name] = nil - name = ":" .. root_nspace .. ":" - .. table.concat(name, ":") - elseif name[#name] == false then - name[#name] = nil - name = ":" .. root_nspace .. "-include:" - .. table.concat(name, ":") - else - name = table.concat(name, ":") - end - end - self:write_raw("{{", it_to_tp[tp], ">", name); - if flags then - if tp == self.INCLUDE_SECTION and flags.section then - self:write_raw("#", flags.section) - end - flags.section = nil - local flstr = {} - for k, v in pairs(flags) do - local allow = allowed_incflags[k] - if allow ~= nil then - if type(allow) == "boolean" then - flstr[#flstr + 1] = k - elseif type(allow) == "number" or type(allow) == "string" then - if type(v) ~= type(allow) then - error("invalid value type for flag " .. k) - end - flstr[#flstr + 1] = k .. "=" .. v - elseif type(allow) == "table" then - if type(allow[1]) == "table" then - local valid = false - for i, vv in ipairs(allow[1]) do - if v == vv then - flstr[#flstr + 1] = k .. "=" .. v - valid = true - break - end - end - if not valid then - error("invalid value " .. v .. " for flag " .. k) - end - elseif type(allow[1]) == "string" and - type(allow[2]) == "string" then - if v then - flstr[#flstr + 1] = allow[1] - else - flstr[#flstr + 1] = allow[2] - end - end - end - else - error("invalid include flag: " .. tostring(k)) - end - end - flstr = table.concat(flstr, "&") - if #flstr > 0 then - self:write_raw("&", flstr) - end - end - self:write_raw("}}") - self:write_nl() - return self -end - -M.set_backend = function(bend) - M.Writer = assert(writers[bend], "invalid generation backend") - M.Buffer = M.Writer:clone(Buffer) -end - -writers["dokuwiki"] = util.Object:clone { - INCLUDE_PAGE = 0, - INCLUDE_SECTION = 1, - INCLUDE_NAMESPACE = 2, - INCLUDE_TAG = 3, - - __ctor = function(self, path, title) - local subs - if type(path) == "table" then - subs = dutil.path_join(unpack(path)) - else - subs = dutil.nspace_to_path(path) - end - dutil.mkdir_p(subs) - self.file = assert(io.open(dutil.make_page(subs, "txt"), "w")) - if title then - if M.has_feature("title") then - self:write_raw("~~Title: ", title, "~~") - self:write_nl() - else - self:write_h(title, 1) - end - end - end, - - write_raw = function(self, ...) - self.file:write(...) - return self - end, - - write_nl = function(self, n) - self:write_raw(("\n"):rep(n or 1)) - return self - end, - - write_h = function(self, heading, level, nonl) - local s = ("="):rep(7 - level) - self:write_raw(s, " ", heading, " ", s, "\n") - if not nonl then - self:write_nl() - end - return self - end, - - write_include = function(self, tp, name, flags) - return write_include(self, tp, name, flags) - end, - - write_editable = function(self, ns, name) - ns[#ns + 1] = name - ns[#ns + 1] = false - self:write_include(self.INCLUDE_PAGE, ns, { - date = false, user = false, link = false - }) - -- restore the table for later reuse - -- the false gets deleted by write_include - ns[#ns] = nil - end, - - write_inherited = function(self, ns) - ns[#ns + 1] = true - self:write_include(self.INCLUDE_PAGE, ns, { - editbutton = false, date = false, user = false, link = false - }) - end, - - write_fmt = function(self, fmt1, fmt2, ...) - self:write_raw(fmt1, ...) - self:write_raw(fmt2) - return self - end, - - write_b = function(self, ...) - self:write_fmt("**", "**", ...) - return self - end, - - write_i = function(self, ...) - self:write_fmt("//", "//", ...) - return self - end, - - write_u = function(self, ...) - self:write_fmt("__", "__", ...) - return self - end, - - write_s = function(self, ...) - self:write_fmt("", "", ...) - return self - end, - - write_m = function(self, ...) - self:write_fmt("''", "''", ...) - return self - end, - - write_sub = function(self, ...) - self:write_fmt("", "", ...) - return self - end, - - write_sup = function(self, ...) - self:write_fmt("", "", ...) - return self - end, - - write_br = function(self, nl) - self:write_raw("\\\\", nl and "\n" or " ") - return self - end, - - write_pre_inline = function(self, ...) - self:write_fmt("%%", "%%", ...) - return self - end, - - write_pre = function(self, ...) - self:write_fmt("\n", "\n", ...) - return self - end, - - write_code = function(self, str, lang) - lang = lang and (" " .. lang) or "" - self:write_raw("\n", str, "\n\n") - end, - - write_link = function(self, target, title) - if type(target) == "table" then - if target[#target] == false then - target[#target] = nil - target = ":" .. root_nspace .. "-include:" - .. table.concat(target, ":") - else - target[#target] = nil - target = ":" .. root_nspace .. ":" - .. table.concat(target, ":") - end - end - if not title then - self:write_raw("[[", target:lower(), "|", target, "]]") - return - end - target = target:lower() - if type(title) == "string" then - self:write_raw("[[", target, "|", title, "]]") - return self - end - self:write_raw("[[", target, "|") - title(self) - self:write_raw("]]") - return self - end, - - write_table = function(self, titles, tbl) - if titles then - self:write_raw("^ ", table.concat(titles, " ^ "), " ^\n") - end - for i, v in ipairs(tbl) do - self:write_raw("| ", table.concat(v, " | "), " |\n") - end - return self - end, - - write_list = function(self, tbl, ord) - local prec = ord and "-" or "*" - for i, v in ipairs(tbl) do - local lvl, str = 1, v - if type(v) == "table" then - lvl, str = v[1] + 1, v[2] - end - local pbeg, pend = str:match("([^\n]+)\n(.+)") - if not pbeg then - pbeg = str - end - self:write_raw((" "):rep(lvl), prec, " ", str, "\n") - if pend then - self:write_raw(pend, "\n") - end - end - return self - end, - - write_par = function(self, str) - local tokp = dtree.DocTokenizer(str) - local notetypes = M.has_feature("notes") and { - [tokp.MARK_NOTE] = "\n", - [tokp.MARK_WARNING] = "\n", - [tokp.MARK_REMARK] = "\n", - [tokp.MARK_TODO] = "\n**TODO:** " - } or {} - local hasraw, hasnote = false, false - while tokp:tokenize() do - local tp = tokp:type_get() - local tag = notetypes[tp] - if tag then - self:write_raw(tag) - hasnote = true - else - if not hasraw then - self:write_raw("%%") - hasraw = true - end - if tp == tokp.REF then - local reft = tokp:ref_resolve(true) - local str = tokp:text_get() - if str:sub(1, 1) == "[" then - str = str:sub(2, #str - 1) - end - self:write_raw("%%") - self:write_link(reft, str) - self:write_raw("%%") - else - local str = tokp:text_get() - assert(str, "internal tokenizer error") - -- replace possible %% chars - str = str:gsub("%%%%", "%%%%%%%%%%%%") - if tp == tokp.MARKUP_MONOSPACE then - self:write_raw("%%''" .. str .. "''%%") - else - self:write_raw(str) - end - end - end - end - self:write_raw("%%") - if hasnote then - self:write_raw("\n") - end - return self - end, - - write_folded = function(self, title, func) - if M.has_feature("folds") then - self:write_raw("++++ ", title, " |\n\n") - end - func(self) - if M.has_feature("folds") then - self:write_raw("\n\n++++") - end - return self - end, - - finish = function(self) - self.file:close() - end -} - -M.init = function(root_ns, ftrs) - root_nspace = root_ns - features = ftrs -end - -return M diff --git a/src/scripts/elua/apps/gendoc.lua b/src/scripts/elua/apps/gendoc.lua deleted file mode 100644 index 36c47e2af3..0000000000 --- a/src/scripts/elua/apps/gendoc.lua +++ /dev/null @@ -1,1804 +0,0 @@ -local getopt = require("getopt") - -local serializer = require("serializer") - -local stats = require("docgen.stats") -local dutil = require("docgen.util") -local writer = require("docgen.writer") -local keyref = require("docgen.keyref") -local dtree = require("docgen.doctree") -local mono = require("docgen.mono") - -local printgen = function() end - -local propt_to_type = { - [dtree.Function.PROPERTY] = "(get, set)", - [dtree.Function.PROP_GET] = "(get)", - [dtree.Function.PROP_SET] = "(set)", -} - -local gen_cparam = function(par, out) - local part = par:type_get() - out = out or (par:direction_get() == par.OUT) - local tstr = part:c_type_get() - if out then - tstr = dtree.type_cstr_get(tstr, "*") - end - return dtree.type_cstr_get(tstr, par:name_get()) -end - -local get_func_csig_part = function(cn, tp) - if not tp then - return "void " .. cn - end - return dtree.type_cstr_get(tp, cn) -end - -local gen_func_csig = function(f, ftype) - ftype = ftype or f.METHOD - assert(ftype ~= f.PROPERTY) - - local cn = f:full_c_name_get(ftype) - local rtype = f:return_type_get(ftype) - - local fparam = "Eo *obj" - if f:is_class() then - fparam = "Efl_Class *klass" - elseif f:is_const() or ftype == f.PROP_GET then - fparam = "const Eo *obj" - end - - if f:type_get() == f.METHOD then - local pars = f:parameters_get() - local cnrt = get_func_csig_part(cn, rtype) - for i = 1, #pars do - pars[i] = gen_cparam(pars[i]) - end - table.insert(pars, 1, fparam); - return cnrt .. "(" .. table.concat(pars, ", ") .. ");" - end - - local keys = f:property_keys_get(ftype) - local vals = f:property_values_get(ftype) - - if ftype == f.PROP_SET then - local cnrt = get_func_csig_part(cn, rtype) - local pars = {} - for i, par in ipairs(keys) do - pars[#pars + 1] = gen_cparam(par) - end - for i, par in ipairs(vals) do - pars[#pars + 1] = gen_cparam(par) - end - table.insert(pars, 1, fparam); - return cnrt .. "(" .. table.concat(pars, ", ") .. ");" - end - - -- getters - local cnrt - if not rtype then - if #vals == 1 then - cnrt = get_func_csig_part(cn, vals[1]:type_get()) - table.remove(vals, 1) - else - cnrt = get_func_csig_part(cn) - end - else - cnrt = get_func_csig_part(cn, rtype) - end - local pars = {} - for i, par in ipairs(keys) do - pars[#pars + 1] = gen_cparam(par) - end - for i, par in ipairs(vals) do - pars[#pars + 1] = gen_cparam(par, true) - end - table.insert(pars, 1, fparam); - return cnrt .. "(" .. table.concat(pars, ", ") .. ");" -end - -local gen_func_namesig = function(fn, cl, buf, isprop, isget, isset) - if isprop then - buf[#buf + 1] = "@property " - end - buf[#buf + 1] = fn:name_get() - buf[#buf + 1] = " " - if fn:is_beta() then - buf[#buf + 1] = "@beta " - end - if not isprop then - if fn:scope_get(fn.METHOD) == fn.scope.PROTECTED then - buf[#buf + 1] = "@protected " - end - elseif isget and isset then - if fn:scope_get(fn.PROP_GET) == fn.scope.PROTECTED and - fn:scope_get(fn.PROP_SET) == fn.scope.PROTECTED then - buf[#buf + 1] = "@protected " - end - end - if fn:is_class() then - buf[#buf + 1] = "@class " - end - if fn:is_const() then - buf[#buf + 1] = "@const " - end -end - -local gen_func_param = function(fp, buf, nodir) - -- TODO: default value - buf[#buf + 1] = " " - local dirs = { - [dtree.Parameter.IN] = "@in ", - [dtree.Parameter.OUT] = "@out ", - [dtree.Parameter.INOUT] = "@inout ", - } - if not nodir then buf[#buf + 1] = dirs[fp:direction_get()] end - buf[#buf + 1] = fp:name_get() - buf[#buf + 1] = ": " - buf[#buf + 1] = fp:type_get():serialize() - local dval = fp:default_value_get() - if dval then - buf[#buf + 1] = " (" - buf[#buf + 1] = dval:serialize() - buf[#buf + 1] = ")" - end - if fp:is_nonull() then - buf[#buf + 1] = " @nonull" - end - if fp:is_nullable() then - buf[#buf + 1] = " @nullable" - end - if fp:is_optional() then - buf[#buf + 1] = " @optional" - end - buf[#buf + 1] = ";\n" -end - -local gen_func_return = function(fp, ftype, buf, indent) - local rett = fp:return_type_get(ftype) - if not rett then - return - end - buf[#buf + 1] = indent and (" "):rep(indent) or " " - buf[#buf + 1] = "return: " - buf[#buf + 1] = rett:serialize() - local dval = fp:return_default_value_get(ftype) - if dval then - buf[#buf + 1] = " (" - buf[#buf + 1] = dval:serialize() - buf[#buf + 1] = ")" - end - if fp:return_is_warn_unused(ftype) then - buf[#buf + 1] = " @warn_unused" - end - buf[#buf + 1] = ";\n" -end - -local gen_method_sig = function(fn, cl) - local buf = {} - gen_func_namesig(fn, cl, buf, false, false, false) - - local fimp = fn:implement_get() - - if fimp:is_pure_virtual(fn.METHOD) then - buf[#buf + 1] = "@pure_virtual " - end - buf[#buf + 1] = "{" - local params = fn:parameters_get() - local rtp = fn:return_type_get(fn.METHOD) - if #params == 0 and not rtp then - buf[#buf + 1] = "}" - return table.concat(buf) - end - buf[#buf + 1] = "\n" - if #params > 0 then - buf[#buf + 1] = " params {\n" - for i, fp in ipairs(params) do - gen_func_param(fp, buf) - end - buf[#buf + 1] = " }\n" - end - gen_func_return(fn, fn.METHOD, buf) - buf[#buf + 1] = "}" - return table.concat(buf) -end - -local eovals_check_same = function(a1, a2) - if #a1 ~= #a2 then return false end - for i, v in ipairs(a1) do - if v ~= a2[i] then return false end - end - return true -end - -local gen_prop_keyvals = function(tbl, kword, buf, indent) - local ind = indent and (" "):rep(indent) or " " - if #tbl == 0 then return end - buf[#buf + 1] = " " - buf[#buf + 1] = ind - buf[#buf + 1] = kword - buf[#buf + 1] = " {\n" - for i, v in ipairs(tbl) do - buf[#buf + 1] = ind - gen_func_param(v, buf, true) - end - buf[#buf + 1] = " " - buf[#buf + 1] = ind - buf[#buf + 1] = "}\n" -end - -local gen_prop_sig = function(fn, cl) - local buf = {} - local fnt = fn:type_get() - local isget = (fnt == fn.PROPERTY or fnt == fn.PROP_GET) - local isset = (fnt == fn.PROPERTY or fnt == fn.PROP_SET) - gen_func_namesig(fn, cl, buf, true, isget, isset) - - local pimp = fn:implement_get() - - local gvirt = pimp:is_pure_virtual(fn.PROP_GET) - local svirt = pimp:is_pure_virtual(fn.PROP_SET) - - if (not isget or gvirt) and (not isset or svirt) then - buf[#buf + 1] = "@pure_virtual " - end - - local gkeys = isget and fn:property_keys_get(fn.PROP_GET) or {} - local skeys = isset and fn:property_keys_get(fn.PROP_SET) or {} - local gvals = isget and fn:property_values_get(fn.PROP_GET) or {} - local svals = isget and fn:property_values_get(fn.PROP_SET) or {} - local grtt = isget and fn:return_type_get(fn.PROP_GET) or nil - local srtt = isset and fn:return_type_get(fn.PROP_SET) or nil - - local keys_same = eovals_check_same(gkeys, skeys) - local vals_same = eovals_check_same(gvals, svals) - - buf[#buf + 1] = "{\n" - - if isget then - buf[#buf + 1] = " get " - if fn:scope_get(fn.PROP_GET) == fn.scope.PROTECTED and - fn:scope_get(fn.PROP_SET) ~= fn.scope.PROTECTED then - buf[#buf + 1] = "@protected " - end - buf[#buf + 1] = "{" - if (#gkeys == 0 or keys_same) and (#gvals == 0 or vals_same) and - (not grtt or grtt == srtt) then - buf[#buf + 1] = "}\n" - else - buf[#buf + 1] = "\n" - if not keys_same then gen_prop_keyvals(gkeys, "keys", buf) end - if not vals_same then gen_prop_keyvals(gvals, "values", buf) end - if grtt ~= srtt then - gen_func_return(fn, fn.PROP_GET, buf, 2) - end - buf[#buf + 1] = " }\n" - end - end - - if isset then - buf[#buf + 1] = " set " - if fn:scope_get(fn.PROP_SET) == fn.scope.PROTECTED and - fn:scope_get(fn.PROP_GET) ~= fn.scope.PROTECTED then - buf[#buf + 1] = "@protected " - end - buf[#buf + 1] = "{" - if (#skeys == 0 or keys_same) and (#svals == 0 or vals_same) and - (not srtt or grtt == srtt) then - buf[#buf + 1] = "}\n" - else - buf[#buf + 1] = "\n" - if not keys_same then gen_prop_keyvals(skeys, "keys", buf) end - if not vals_same then gen_prop_keyvals(svals, "values", buf) end - if grtt ~= srtt then - gen_func_return(fn, fn.PROP_SET, buf, 2) - end - buf[#buf + 1] = " }\n" - end - end - - if keys_same then gen_prop_keyvals(gkeys, "keys", buf, 0) end - if vals_same then gen_prop_keyvals(gvals, "values", buf, 0) end - - buf[#buf + 1] = "}" - return table.concat(buf) -end - --- builders - -local nspaces_group = function(ns) - if #ns <= 2 then - return ns[1] - end - - if ns[1] == "efl" and (ns[2] == "class" or ns[2] == "interface" or - ns[2] == "object" or ns[2] == "promise") then - return ns[1] - end - - return ns[1] .. "." .. ns[2] -end - -local nspaces_filter = function(items, ns) - local out = {} - - for _, item in ipairs(items) do - local group = nspaces_group(item:nspaces_get()) - if group == ns then out[#out + 1] = item end - end - - return out -end - -local build_method, build_property, build_event - -local build_reftable = function(f, title, ctype, t, iscl) - if not t or #t == 0 then - return - end - - local nt = {} - for i, v in ipairs(t) do - nt[#nt + 1] = { - writer.Buffer():write_link( - iscl and v:nspaces_get(true) - or dtree.Node.nspaces_get(v, true), - v:name_get() - ):finish(), - v:doc_get():brief_get() - } - end - table.sort(nt, function(v1, v2) return v1[1] < v2[1] end) - f:write_table({ title, "Brief description" }, nt) -end - -local build_ref_group = function(f, ns, classlist, aliases, structs, enums, consts, globals) - local classes = {} - local ifaces = {} - local mixins = {} - - for i, cl in ipairs(classlist) do - local tp = cl:type_get() - if tp == dtree.Class.REGULAR or tp == dtree.Class.ABSTRACT then - classes[#classes + 1] = cl - elseif tp == dtree.Class.MIXIN then - mixins[#mixins + 1] = cl - elseif tp == dtree.Class.INTERFACE then - ifaces[#ifaces + 1] = cl - end - end - - local title = ns:gsub("(%l)(%w*)", function(a,b) return a:upper()..b end) --string.sub(ns, 1, 1):upper() .. string.sub(ns, 2):lower() - f:write_h(title, 2) - - build_reftable(f, "Classes", "class", classes, true) - build_reftable(f, "Interfaces", "interface", ifaces, true) - build_reftable(f, "Mixins", "mixin", mixins, true) - - build_reftable(f, "Aliases", "alias", aliases) - build_reftable(f, "Structures", "struct", structs) - build_reftable(f, "Enums", "enum", enums) - build_reftable(f, "Constants", "constant", consts) - build_reftable(f, "Globals", "global", globals) - - f:write_nl() -end - -local build_ref = function() - local f = writer.Writer("start", "EFL Reference") - printgen("Generating reference...") - - f:write_editable({ "reference" }, "general") - f:write_nl() - - local classlist = dtree.Class.all_get() - local aliases = dtree.Typedecl.all_aliases_get() - local structs = dtree.Typedecl.all_structs_get() - local enums = dtree.Typedecl.all_enums_get() - local consts = dtree.Variable.all_constants_get() - local globals = dtree.Variable.all_globals_get() - - grouped = {} - groups = {} - for i, cl in ipairs(classlist) do - local ns = cl:nspaces_get() - local name = nspaces_group(cl:nspaces_get()) - - local group = grouped[name] - if not group then - group = {} - grouped[name] = group - groups[#groups + 1] = name - end - - group[#group + 1] = cl - end - table.sort(groups) - - for _, ns in ipairs(groups) do - build_ref_group(f, ns, grouped[ns], nspaces_filter(aliases, ns), nspaces_filter(structs, ns), - nspaces_filter(enums, ns), nspaces_filter(consts, ns), nspaces_filter(globals, ns)) - end - - f:finish() -end - -local build_inherits -build_inherits = function(cl, t, lvl) - t = t or {} - lvl = lvl or 0 - local lbuf = writer.Buffer() - if lvl > 0 then - lbuf:write_link(cl:nspaces_get(true), cl:name_get()) - lbuf:write_raw(" ") - lbuf:write_i("(" .. cl:type_str_get() .. ")") - - t[#t + 1] = { lvl - 1, lbuf:finish() } - end - - for i, acl in ipairs(cl:inherits_get()) do - build_inherits(acl, t, lvl + 1) - end - return t -end - -local build_inherit_summary -build_inherit_summary = function(cl, buf) - buf = buf or writer.Buffer() - buf:write_raw(" => ") - - buf:write_link(cl:nspaces_get(true), cl:name_get()) - buf:write_raw(" ") - buf:write_i("(" .. cl:type_str_get() .. ")") - - local inherits = cl:inherits_get() - if #inherits ~= 0 then - build_inherit_summary(inherits[1], buf) - end - return buf -end - -local default_theme_light = { - classes = { - regular = { - style = "filled", - color = "black", - fill_color = "white", - font_color = "black", - primary_color = "black", - primary_fill_color = "gray", - primary_font_color = "black" - }, - abstract = { - style = "filled", - color = "black", - fill_color = "white", - font_color = "black", - primary_color = "black", - primary_fill_color = "gray", - primary_font_color = "black" - }, - mixin = { - style = "filled", - color = "blue", - fill_color = "white", - font_color = "black", - primary_color = "blue", - primary_fill_color = "skyblue", - primary_font_color = "black" - }, - interface = { - style = "filled", - color = "cornflowerblue", - fill_color = "white", - font_color = "black", - primary_color = "cornflowerblue", - primary_fill_color = "azure", - primary_font_color = "black" - } - }, - node = { - shape = "box" - }, - edge = { - color = "black" - }, - bg_color = "transparent", - rank_dir = "TB", - size = "6" -} - -local default_theme_dark = { - classes = { - regular = { - style = "filled", - color = "gray15", - fill_color = "gray15", - font_color = "white", - primary_color = "gray15", - primary_fill_color = "black", - primary_font_color = "white" - }, - abstract = { - style = "filled", - color = "gray15", - fill_color = "gray15", - font_color = "white", - primary_color = "gray15", - primary_fill_color = "black", - primary_font_color = "white" - }, - mixin = { - style = "filled", - color = "deepskyblue", - fill_color = "gray15", - font_color = "white", - primary_color = "deepskyblue", - primary_fill_color = "deepskyblue4", - primary_font_color = "white" - }, - interface = { - style = "filled", - color = "cornflowerblue", - fill_color = "gray15", - font_color = "white", - primary_color = "cornflowerblue", - primary_fill_color = "dodgerblue4", - primary_font_color = "white" - } - }, - node = { - shape = "box" - }, - edge = { - color = "gray35" - }, - bg_color = "transparent", - rank_dir = "TB", - size = "6" -} - -local current_theme = default_theme_dark - -local validate_ctheme = function(tb, name) - if type(tb.classes[name]) ~= "table" then - return false - end - local t = tb.classes[name] - if type(t.style) ~= "string" then - return false - end - if type(t.color) ~= "string" then - return false - end - if type(t.fill_color) ~= "string" then - return false - end - if type(t.font_color) ~= "string" then - return false - end - if not t.primary_color then - t.primary_color = t.color - end - if not t.primary_fill_color then - t.primary_fill_color = t.fill_color - end - if not t.primary_font_color then - t.primary_font_color = t.font_color - end - if type(t.primary_color) ~= "string" then - return false - end - if type(t.primary_fill_color) ~= "string" then - return false - end - if type(t.primary_font_color) ~= "string" then - return false - end - return true -end - -local validate_theme = function(tb) - if type(tb) ~= "table" then - return false - end - if type(tb.classes) ~= "table" then - return false - end - if not tb.node then - tb.node = current_theme.node - end - if not tb.edge then - tb.edge = current_theme.edge - end - if not tb.bg_color then - tb.bg_color = current_theme.bg_color - end - if not tb.rank_dir then - tb.rank_dir = current_theme.rank_dir - end - if not tb.size then - tb.size = current_theme.size - end - if type(tb.node) ~= "table" then - return false - end - if type(tb.edge) ~= "table" then - return false - end - if type(tb.bg_color) ~= "string" then - return false - end - if type(tb.rank_dir) ~= "string" then - return false - end - if type(tb.size) ~= "string" then - return false - end - if not validate_ctheme(tb, "regular") then - return false - end - if not validate_ctheme(tb, "abstract") then - return false - end - if not validate_ctheme(tb, "mixin") then - return false - end - if not validate_ctheme(tb, "interface") then - return false - end - return true -end - -local set_theme = function(tname) - local tf = io.open(tname) - if tf then - local cont = tf:read("*all") - tf:close() - local tb, err = serializer.deserialize(cont) - if not tb then - error("error parsing theme '" .. tname .. "': " .. err) - end - if not validate_theme(tb) then - error("invalid theme '" .. tname .. "'") - end - current_theme = tb - else - error("theme '" .. tname .. "' does not exist") - end -end - -local find_parent_impl -find_parent_impl = function(fulln, cl) - for i, pcl in ipairs(cl:inherits_get()) do - for j, impl in ipairs(pcl:implements_get()) do - if impl:name_get() == fulln then - return impl, pcl - end - end - local pimpl, pcl = find_parent_impl(fulln, pcl) - if pimpl then - return pimpl, pcl - end - end - return nil, cl -end - -local find_parent_briefdoc -find_parent_briefdoc = function(fulln, cl) - local pimpl, pcl = find_parent_impl(fulln, cl) - if not pimpl then - return dtree.Doc():brief_get() - end - local pdoc = pimpl:doc_get(dtree.Function.METHOD, true) - local pdocf = pimpl:fallback_doc_get(true) - if not pdoc:exists() and (not pdocf or not pdocf:exists()) then - return find_parent_briefdoc(fulln, pcl) - end - return pdoc:brief_get(pdocf) -end - -local build_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = {} - for i, implt in ipairs(tbl) do - local lbuf = writer.Buffer() - - local cl, impl = unpack(implt) - local func = impl:function_get() - - local wt = {} - wt[0] = cl - wt[1] = func - wt[2] = impl - - nt[#nt + 1] = wt - end - - local get_best_scope = function(f) - local ft = f:type_get() - if ft == f.PROPERTY then - local fs1, fs2 = f:scope_get(f.PROP_GET), f:scope_get(f.PROP_SET) - if fs1 == f.scope.PUBLIC or fs2 == f.scope.PUBLIC then - return f.scope.PUBLIC - elseif fs1 == f.scope.PROTECTED or fs2 == f.scope.PROTECTED then - return f.scope.PROTECTED - else - return f.scope.PRIVATE - end - else - return f:scope_get(ft) - end - end - table.sort(nt, function(v1, v2) - local cl1, cl2 = v1[0], v2[0] - if cl1 ~= cl2 then - return cl1:name_get() < cl2:name_get() - end - - local f1, f2 = v1[1], v2[1] - local f1s, f2s = get_best_scope(f1), get_best_scope(f2) - if f1s ~= f2s then - if f1s ~= f1.scope.PROTECED then - -- public funcs go first, private funcs go last - return f1s == f1.scope.PUBLIC - else - -- protected funcs go second - return f2s == f2.scope.PRIVATE - end - end - return f1:name_get() < f2:name_get() - end) - - return nt -end - -local write_description = function(f, impl, func, cl) - local over = impl:is_overridden(cl) - local bdoc - - local doc = impl:doc_get(func.METHOD, true) - local docf = impl:fallback_doc_get(true) - if over and (not doc:exists() and (not docf or not docf:exists())) then - bdoc = find_parent_briefdoc(impl:name_get(), cl) - else - bdoc = doc:brief_get(docf) - end - if bdoc ~= "No description supplied." then - f:write_raw(bdoc) - end -end - -local write_function = function(f, func, cl) - local llbuf = writer.Buffer() - llbuf:write_link(func:nspaces_get(cl, true), func:name_get()) - f:write_b(llbuf:finish()) - - local pt = propt_to_type[func:type_get()] - if pt then - f:write_raw(" ") - local llbuf = writer.Buffer() - llbuf:write_b(pt) - f:write_i(llbuf:finish()) - end -end - -local write_scope = function(f, func) - local ftt = { - [func.scope.PROTECTED] = "protected", - [func.scope.PRIVATE] = "private" - } - if func:is_class() then - f:write_raw(" ") - f:write_m("class") - end - if func:type_get() == func.PROPERTY then - local ft1, ft2 = ftt[func:scope_get(func.PROP_GET)], - ftt[func:scope_get(func.PROP_SET)] - if ft1 and ft1 == ft2 then - f:write_raw(" ") - f:write_m(ft1) - elseif ft1 or ft2 then - local s = "" - if ft1 then - s = s .. ft1 .. " get" .. (ft2 and ", " or "") - end - if ft2 then - s = s .. ft2 .. " set" - end - f:write_raw(" ") - f:write_m(s) - end - else - local ft = ftt[func:scope_get(func:type_get())] - if ft then - f:write_raw(" ") - f:write_m(ft) - end - end -end - -local write_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_functable(t, tcl, tbl) - - local wrote = false - for i, wt in ipairs(nt) do - local cl = wt[0] - local func = wt[1] - local impl = wt[2] - - local ocl = impl:class_get() - local func = impl:function_get() - local over = impl:is_overridden(cl) - - -- function - write_function(f, func, cl) - -- scope - write_scope(f, func) - - -- overrides - if over then - -- TODO: possibly also mention which part of a property was - -- overridden and where, get/set override point might differ! - -- but we get latest doc every time so it's ok for now - local llbuf = writer.Buffer() - llbuf:write_raw(" [Overridden from ") - llbuf:write_link(ocl:nspaces_get(true), ocl:name_get()) - llbuf:write_raw("]") - f:write_i(llbuf:finish()) - end - - -- description - f:write_br(true) - f:write_raw("> ") - write_description(f, impl, func, cl) - - -- code snippets - f:write_nl() - local codes = {} - if func:type_get() ~= dtree.Function.PROPERTY then - codes[#codes + 1] = gen_func_csig(func, func:type_get()) - else - codes[#codes + 1] = gen_func_csig(func, dtree.Function.PROP_GET) - codes[#codes + 1] = gen_func_csig(func, dtree.Function.PROP_SET) - end - f:write_code(table.concat(codes, "\n"), "c") - f:write_br(true) - - if cl == tcl then - if impl:is_prop_get() or impl:is_prop_set() then - build_property(impl, cl) - else - build_method(impl, cl) - end - end - end - f:write_nl() -end - -local write_inherit_functable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_functable(t, tcl, tbl) - - local prevcl = tcl - for i, wt in ipairs(nt) do - local cl = wt[0] - local func = wt[1] - local impl = wt[2] - - local ocl = impl:class_get() - local func = impl:function_get() - - -- class grouping for inheritance - if cl ~= prevcl then - prevcl = cl - f:write_raw("^ ") - f:write_link(cl:nspaces_get(true), cl:name_get()) - f:write_raw(" ^^^") - f:write_nl() - end - - -- scope - f:write_raw("| ") - write_scope(f, func) - f:write_raw(" | ") - -- function - write_function(f, func, cl) - f:write_raw(" | ") - -- description - write_description(f, impl, func, cl) - f:write_raw(" |") - f:write_nl() - end - f:write_nl() -end - --- finds all stuff that is callable on a class, respecting --- overrides and not duplicating, does a depth-first search -local find_callables -find_callables = function(cl, omeths, events, written) - for i, pcl in ipairs(cl:inherits_get()) do - for j, impl in ipairs(pcl:implements_get()) do - local func = impl:function_get() - local fid = func:id_get() - if not written[fid] then - omeths[#omeths + 1] = { pcl, impl } - written[fid] = true - end - end - for i, ev in ipairs(pcl:events_get()) do - local evid = ev:name_get() - if not written[evid] then - events[#events + 1] = { pcl, ev } - written[evid] = true - end - end - find_callables(pcl, omeths, events, written) - end -end - -local build_evcsig = function(ev) - local csbuf = { ev:c_name_get(), "(" } - csbuf[#csbuf + 1] = dtree.type_cstr_get(ev:type_get()) - if ev:is_beta() then - csbuf[#csbuf + 1] = ", @beta" - end - if ev:is_hot() then - csbuf[#csbuf + 1] = ", @hot" - end - if ev:is_restart() then - csbuf[#csbuf + 1] = ", @restart" - end - csbuf[#csbuf + 1] = ")"; - return table.concat(csbuf) -end - -local build_evtable = function(f, tcl, tbl, newm) - if #tbl == 0 then - return - end - local nt = {} - for i, evt in ipairs(tbl) do - local lbuf = writer.Buffer() - local evn - local cl, ev - if not newm then - cl, ev = evt[1], evt[2] - else - cl, ev = tcl, evt - end - - local wt = {} - wt[0] = cl - wt[1] = ev - wt[2] = ev:name_get() - - nt[#nt + 1] = wt - end - - table.sort(nt, function(v1, v2) - if v1[0] ~= v2[0] then - return v1[0]:name_get() < v2[0]:name_get() - end - - return v1[2] < v2[2] - end) - - return nt -end - -local write_event_scope = function(f, ev) - local ett = { - [ev.scope.PROTECTED] = "protected", - [ev.scope.PRIVATE] = "private" - } - local ets = ett[ev:scope_get()] - if ets then - f:write_raw(" ") - f:write_m(ets) - end -end - -local write_evtable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_evtable(f, tcl, tbl, true) - for i, wt in ipairs(nt) do - local evn - local cl, ev = wt[0], wt[1] - - local llbuf = writer.Buffer() - llbuf:write_link(ev:nspaces_get(cl, true), wt[2]) - f:write_b(llbuf:finish()) - - -- scope - write_event_scope(f, ev) - - -- description - local bdoc = ev:doc_get():brief_get() - if bdoc ~= "No description supplied." then - f:write_br(true) - f:write_raw("> ") - f:write_raw(bdoc) - end - - f:write_nl() - f:write_code(build_evcsig(ev), "c"); - f:write_br() - - if cl == tcl then - build_event(ev, cl) - end - end -end - - -local write_inherit_evtable = function(f, tcl, tbl) - if #tbl == 0 then - return - end - local nt = build_evtable(f, tcl, tbl, false) - local prevcl - for i, wt in ipairs(nt) do - local evn - local cl, ev = wt[0], wt[1] - - if cl ~= prevcl then - prevcl = cl - f:write_raw("^ ") - f:write_link(cl:nspaces_get(true), cl:name_get()) - f:write_raw(" ^^^") - f:write_nl() - end - - f:write_raw("| ") - -- scope - write_event_scope(f, ev) - f:write_raw(" | ") - - local llbuf = writer.Buffer() - llbuf:write_link(ev:nspaces_get(cl, true), wt[2]) - f:write_b(llbuf:finish()) - - f:write_raw(" | ") - local bdoc = ev:doc_get():brief_get() - if bdoc ~= "No description supplied." then - f:write_raw(bdoc) - end - - f:write_raw(" |") - f:write_nl() - end -end - -local build_class = function(cl) - local cln = cl:nspaces_get() - local fulln = cl:name_get() - local f = writer.Writer(cln, fulln) - printgen("Generating class: " .. fulln) - - mono.build_class(cl) - - f:write_h(cl:name_get() .. " (" .. cl:type_str_get() .. ")", 1) - - f:write_h("Description", 2) - f:write_raw(cl:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(cln, "description") - f:write_nl() - - local inherits = cl:inherits_get() - if #inherits ~= 0 then - f:write_h("Inheritance", 2) - - f:write_raw(build_inherit_summary(inherits[1]):finish()) - f:write_nl() - - f:write_folded("Full hierarchy", function() - f:write_list(build_inherits(cl)) - end) - f:write_nl() - end - - local written = {} - local ievs = {} - local meths, omeths = {}, {} - for i, impl in ipairs(cl:implements_get()) do - local func = impl:function_get() - written[func:id_get()] = true - meths[#meths + 1] = { cl, impl } - end - find_callables(cl, omeths, ievs, written) - - f:write_h("Members", 2) - write_functable(f, cl, meths, true) - if #omeths ~= 0 then - f:write_h("Inherited", 3) - end - write_inherit_functable(f, cl, omeths, false) - - f:write_h("Events", 2) - write_evtable(f, cl, cl:events_get(), true) - if #ievs ~= 0 then - f:write_h("Inherited", 3) - end - write_inherit_evtable(f, cl, ievs, false) - - f:finish() -end - -local build_classes = function() - for i, cl in ipairs(dtree.Class.all_get()) do - build_class(cl) - end -end - -local write_tsigs = function(f, tp, ns) - f:write_h("Signature", 2) - f:write_code(tp:serialize()) - f:write_nl() - - f:write_h("C signature", 2) - f:write_code(tp:serialize_c(ns), "c") - f:write_nl() -end - -local build_alias = function(tp) - local ns = dtree.Node.nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating alias: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(tp:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_struct = function(tp) - local ns = dtree.Node.nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating struct: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(tp:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - f:write_h("Fields", 2) - - f:write_editable(ns, "fields") - f:write_nl() - - local arr = {} - for i, fl in ipairs(tp:struct_fields_get()) do - local buf = writer.Buffer() - buf:write_b(fl:name_get()) - buf:write_raw(" - ", fl:doc_get():full_get()) - arr[#arr + 1] = buf:finish() - end - f:write_list(arr) - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_enum = function(tp) - local ns = dtree.Node.nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating enum: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(tp:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - f:write_h("Fields", 2) - - f:write_editable(ns, "fields") - f:write_nl() - - local arr = {} - for i, fl in ipairs(tp:enum_fields_get()) do - local buf = writer.Buffer() - buf:write_b(fl:name_get()) - buf:write_raw(" - ", fl:doc_get():full_get()) - arr[#arr + 1] = buf:finish() - end - f:write_list(arr) - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_variable = function(v, constant) - local ns = v:nspaces_get() - local fulln = v:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating variable: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(v:doc_get():full_get(nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - write_tsigs(f, v, ns) - - f:finish() -end - -local build_typedecls = function() - for i, tp in ipairs(dtree.Typedecl.all_aliases_get()) do - build_alias(tp) - end - - for i, tp in ipairs(dtree.Typedecl.all_structs_get()) do - build_struct(tp) - end - - for i, tp in ipairs(dtree.Typedecl.all_enums_get()) do - build_enum(tp) - end -end - -local build_variables = function() - for i, v in ipairs(dtree.Variable.all_constants_get()) do - build_variable(v, true) - end - - for i, v in ipairs(dtree.Variable.all_globals_get()) do - build_variable(v, false) - end -end - -local build_parlist = function(f, pl, nodir) - local params = {} - for i, p in ipairs(pl) do - local buf = writer.Buffer() - buf:write_b(p:name_get()) - if not nodir then - buf:write_raw(" ") - buf:write_i("(", p:direction_name_get(), ")") - end - buf:write_raw(" - ", p:doc_get():full_get()) - params[#params + 1] = buf:finish() - end - f:write_list(params) -end - -local build_vallist = function(f, pg, ps, title) - if #pg == #ps then - local same = true - for i = 1, #pg do - if not pg[i]:is_same(ps[i]) then - same = false - break - end - end - if same then ps = {} end - end - if #pg > 0 or #ps > 0 then - f:write_h(title, 2) - if #pg > 0 then - if #ps > 0 then - f:write_h("Getter", 3) - end - build_parlist(f, pg, true) - end - if #ps > 0 then - if #pg > 0 then - f:write_h("Setter", 3) - end - build_parlist(f, ps, true) - end - end -end - -local find_parent_doc -find_parent_doc = function(fulln, cl, ftype) - local pimpl, pcl = find_parent_impl(fulln, cl) - if not pimpl then - return dtree.Doc() - end - local pdoc = pimpl:doc_get(ftype) - if not pdoc:exists() then - return find_parent_doc(fulln, pcl, ftype) - end - return pdoc -end - -local write_inherited_from = function(f, impl, cl, over, prop) - if not over then - return - end - local buf = writer.Buffer() - buf:write_raw("Overridden from ") - local pimpl, pcl = find_parent_impl(impl:name_get(), cl) - buf:write_link( - impl:function_get():nspaces_get(pcl, true), impl:name_get() - ) - if prop then - buf:write_raw(" ") - local lbuf = writer.Buffer() - lbuf:write_raw("(") - if impl:is_prop_get() then - lbuf:write_raw("get") - if impl:is_prop_set() then - lbuf:write_raw(", ") - end - end - if impl:is_prop_set() then - lbuf:write_raw("set") - end - lbuf:write_raw(")") - buf:write_b(lbuf:finish()) - end - buf:write_raw(".") - f:write_i(buf:finish()) -end - -local impls_of = {} - -local get_all_impls_of -get_all_impls_of = function(tbl, cl, fn, got) - local cfn = cl:name_get() - if got[cfn] then - return - end - got[cfn] = true - for i, imp in ipairs(cl:implements_get()) do - local ofn = imp:function_get() - if ofn:is_same(fn) then - tbl[#tbl + 1] = cl - break - end - end - for i, icl in ipairs(cl:children_get()) do - get_all_impls_of(tbl, icl, fn, got) - end -end - -local write_ilist = function(f, impl, cl) - local fn = impl:function_get() - local fnn = fn:name_get() - local ocl = fn:implement_get():class_get() - local onm = ocl:name_get() .. "." .. fnn - local imps = impls_of[onm] - if not imps then - imps = {} - impls_of[onm] = imps - get_all_impls_of(imps, ocl, fn, {}) - end - - f:write_h("Implemented by", 2) - local t = {} - for i, icl in ipairs(imps) do - local buf = writer.Buffer() - local cfn = icl:name_get() .. "." .. fnn - if icl:is_same(cl) then - buf:write_b(cfn) - else - buf:write_link(fn:nspaces_get(icl, true), cfn) - end - t[#t + 1] = buf:finish() - end - f:write_list(t) -end - -build_method = function(impl, cl) - local over = impl:is_overridden(cl) - local fn = impl:function_get() - local mns = fn:nspaces_get(cl) - local methn = cl:name_get() .. "." .. fn:name_get() - local f = writer.Writer(mns, methn) - printgen("Generating method: " .. methn) - - local doc = impl:doc_get(fn.METHOD) - if over and not doc:exists() then - doc = find_parent_doc(impl:name_get(), cl, fn.METHOD) - end - - f:write_h("Description", 2) - f:write_raw(doc:full_get(nil, true)) - f:write_nl() - - f:write_editable(mns, "description") - f:write_nl() - - write_inherited_from(f, impl, cl, over, false) - - f:write_h("Signature", 2) - f:write_code(gen_method_sig(fn, cl)) - f:write_nl() - - f:write_h("C signature", 2) - f:write_code(gen_func_csig(fn, nil), "c") - f:write_nl() - - local pars = fn:parameters_get() - if #pars > 0 then - f:write_h("Parameters", 2) - build_parlist(f, pars) - f:write_nl() - end - - write_ilist(f, impl, cl) - f:write_nl() - - f:finish() -end - -build_property = function(impl, cl) - local over = impl:is_overridden(cl) - local fn = impl:function_get() - local pns = fn:nspaces_get(cl) - local propn = cl:name_get() .. "." .. fn:name_get() - local f = writer.Writer(pns, propn) - printgen("Generating property: " .. propn) - - local pimp = fn:implement_get() - - local isget = pimp:is_prop_get() - local isset = pimp:is_prop_set() - - local doc = impl:doc_get(fn.PROPERTY) - local gdoc = impl:doc_get(fn.PROP_GET) - local sdoc = impl:doc_get(fn.PROP_SET) - - if over then - if not doc:exists() then - doc = find_parent_doc(impl:name_get(), cl, fn.PROPERTY) - end - if isget and not gdoc:exists() then - gdoc = find_parent_doc(impl:name_get(), cl, fn.PROP_GET) - end - if isset and not sdoc:exists() then - sdoc = find_parent_doc(impl:name_get(), cl, fn.PROP_SET) - end - end - - if isget and isset then - f:write_h("Description", 2) - if doc:exists() or (not gdoc:exists() and not sdoc:exists()) then - f:write_raw(doc:full_get(nil, true)) - end - if (isget and gdoc:exists()) or (isset and sdoc:exists()) then - f:write_nl(2) - end - f:write_nl() - f:write_editable(pns, "description") - f:write_nl() - end - - local pgkeys = isget and fn:property_keys_get(fn.PROP_GET) or {} - local pskeys = isset and fn:property_keys_get(fn.PROP_SET) or {} - build_vallist(f, pgkeys, pskeys, "Keys") - - local pgvals = isget and fn:property_values_get(fn.PROP_GET) or {} - local psvals = isset and fn:property_values_get(fn.PROP_SET) or {} - build_vallist(f, pgvals, psvals, "Values") - - if isget and gdoc:exists() then - if isset then - f:write_h("Getter", 3) - else - f:write_h("Description", 2) - end - f:write_raw(gdoc:full_get(nil, true)) - if isset and sdoc:exists() then - f:write_nl(2) - end - if isset then - f:write_nl() - f:write_editable(pns, "getter_description") - f:write_nl() - end - end - - if isset and sdoc:exists() then - if isget then - f:write_h("Setter", 3) - else - f:write_h("Description", 2) - end - f:write_raw(sdoc:full_get(nil, true)) - if isget then - f:write_nl() - f:write_editable(pns, "getter_description") - f:write_nl() - end - end - - f:write_nl() - if not isget or not isset then - f:write_nl() - f:write_br() - f:write_editable(pns, "description") - f:write_nl() - end - - write_inherited_from(f, impl, cl, over, true) - - f:write_h("Signature", 2) - f:write_code(gen_prop_sig(fn, cl)) - f:write_nl() - - f:write_h("C signature", 2) - local codes = {} - if isget then - codes[#codes + 1] = gen_func_csig(fn, fn.PROP_GET) - end - if isset then - codes[#codes + 1] = gen_func_csig(fn, fn.PROP_SET) - end - f:write_code(table.concat(codes, "\n"), "c") - f:write_nl() - - write_ilist(f, impl, cl) - f:write_nl() - - f:finish() -end - -local build_event_example = function(ev) - local evcn = ev:c_name_get() - local evcnl = evcn:lower() - - local dtype = "Data *" - - local tbl = { "static void\n" } - tbl[#tbl + 1] = "on_" - tbl[#tbl + 1] = evcnl - tbl[#tbl + 1] = "(void *data, const Efl_Event *event)\n{\n " - tbl[#tbl + 1] = dtree.type_cstr_get(ev:type_get(), "info = event->info;\n") - tbl[#tbl + 1] = " Eo *obj = event->object;\n " - tbl[#tbl + 1] = dtree.type_cstr_get(dtype, "d = data;\n\n") - tbl[#tbl + 1] = " /* event hander code */\n}\n\n" - tbl[#tbl + 1] = "static void\nsetup_event_handler(Eo *obj, " - tbl[#tbl + 1] = dtree.type_cstr_get(dtype, "d") - tbl[#tbl + 1] = ")\n{\n" - tbl[#tbl + 1] = " efl_event_callback_add(obj, " - tbl[#tbl + 1] = evcn - tbl[#tbl + 1] = ", on_" - tbl[#tbl + 1] = evcnl - tbl[#tbl + 1] = ", d);\n}\n" - - return table.concat(tbl) -end - -build_event = function(ev, cl) - local evn = ev:nspaces_get(cl) - local evnm = cl:name_get() .. ": " .. ev:name_get() - local f = writer.Writer(evn, evnm) - printgen("Generating event: " .. evnm) - - f:write_h("Description", 2) - f:write_raw(ev:doc_get():full_get(nil, true)) - f:write_nl() - - f:write_editable(evn, "description") - f:write_nl() - - f:write_h("Signature", 2) - local buf = { ev:name_get() } - - if ev:scope_get() == ev.scope.PRIVATE then - buf[#buf + 1] = " @private" - elseif ev:scope_get() == ev.scope.PROTECTED then - buf[#buf + 1] = " @protected" - end - - if ev:is_beta() then - buf[#buf + 1] = " @beta" - end - if ev:is_hot() then - buf[#buf + 1] = " @hot" - end - if ev:is_restart() then - buf[#buf + 1] = " @restart" - end - - local etp = ev:type_get() - if etp then - buf[#buf + 1] = ": " - buf[#buf + 1] = etp:serialize() - end - - buf[#buf + 1] = ";" - f:write_code(table.concat(buf)) - f:write_nl() - - f:write_h("C information", 2) - f:write_code(build_evcsig(ev), "c") - f:write_nl() - - f:write_h("C usage", 2) - f:write_code(build_event_example(ev), "c") - f:write_nl() - - f:finish() -end - -local build_stats_keyref = function() - for i, cl in ipairs(dtree.Class.all_get()) do - stats.check_class(cl) - keyref.add(cl:name_get():gsub("%.", "_"), cl:nspaces_get(), "c") - for i, imp in ipairs(cl:implements_get()) do - -- TODO: handle doc overrides in stats system - if not imp:is_overridden(cl) then - local func = imp:function_get() - local fns = func:nspaces_get(cl) - if imp:is_prop_get() or imp:is_prop_set() then - if imp:is_prop_get() then - stats.check_property(func, cl, func.PROP_GET) - keyref.add(func:full_c_name_get(func.PROP_GET), fns, "c") - end - if imp:is_prop_set() then - stats.check_property(func, cl, func.PROP_SET) - keyref.add(func:full_c_name_get(func.PROP_SET), fns, "c") - end - else - stats.check_method(func, cl) - keyref.add(func:full_c_name_get(func.METHOD), fns, "c") - end - end - end - for i, ev in ipairs(cl:events_get()) do - keyref.add(ev:c_name_get(), ev:nspaces_get(cl), "c") - end - end - for i, tp in ipairs(dtree.Typedecl.all_aliases_get()) do - stats.check_alias(tp) - end - for i, tp in ipairs(dtree.Typedecl.all_structs_get()) do - stats.check_struct(tp) - end - for i, tp in ipairs(dtree.Typedecl.all_enums_get()) do - stats.check_enum(tp) - end - for i, v in ipairs(dtree.Variable.all_constants_get()) do - stats.check_constant(v) - end - for i, v in ipairs(dtree.Variable.all_globals_get()) do - stats.check_global(v) - end -end - -getopt.parse { - args = arg, - descs = { - { category = "General" }, - { "h", "help", nil, help = "Show this message.", metavar = "CATEGORY", - callback = getopt.help_cb(io.stdout) - }, - { "v", "verbose", false, help = "Be verbose." }, - { "p", "print-gen", false, help = "Print what is being generated." }, - - { category = "Generator" }, - { "r", "root", true, help = "Root path of the docs." }, - { "n", "namespace", true, help = "Root namespace of the docs." }, - { nil, "graph-theme", true, help = "Optional graph theme." }, - { nil, "graph-theme-light", false, help = "Use light builtin graph theme." }, - { nil, "disable-notes", false, help = "Disable notes plugin usage." }, - { nil, "disable-folded", false, help = "Disable folded plugin usage." }, - { nil, "disable-title", false, help = "Disable title plugin usage." }, - { "m", "use-markdown", false, - help = "Generate Markdown instead of DokuWiki syntax." }, - { nil, "pass", true, help = "The pass to run (optional) " - .. "(rm, ref, clist, classes, types, vars, stats or class name)." } - }, - error_cb = function(parser, msg) - io.stderr:write(msg, "\n") - getopt.help(parser, io.stderr) - end, - done_cb = function(parser, opts, args) - if opts["h"] then - return - end - if opts["p"] then - printgen = function(...) print(...) end - end - if opts["graph-theme-dark"] then - current_theme = default_theme_light - end - if opts["graph-theme"] then - set_theme(opts["graph-theme"]) - end - local rootns = (not opts["n"] or opts["n"] == "") - and "develop:api" or opts["n"] - local dr - if not opts["r"] or opts["r"] == "" then - dr = "dokuwiki/data/pages" - else - dr = opts["r"] - end - dr = dutil.path_join(dr, dutil.nspace_to_path(rootns)) - dutil.init(dr, rootns) - writer.set_backend("dokuwiki") - if #args == 0 then - dtree.scan_directory() - else - for i, p in ipairs(args) do - dtree.scan_directory(p) - end - end - - local st = opts["pass"] - - dtree.parse(st) - - if st == "clist" then - for i, cl in ipairs(dtree.Class.all_get()) do - print(cl:name_get()) - end - return - end - - local wfeatures = { - notes = not opts["disable-notes"], - folds = not opts["disable-folded"], - title = not opts["disable-title"] - } - writer.init(rootns, wfeatures) - if not st or st == "rm" then - dutil.rm_root() - dutil.mkdir_r(nil) - end - if not st or st == "ref" then - build_ref() - end - if not st or st == "classes" then - build_classes() - end - if st and st:match("%.") then - local cl = dtree.Class.by_name_get(st) - if cl then - build_class(cl) - end - end - if not st or st == "types" then - build_typedecls() - end - if not st or st == "vars" then - build_variables() - end - - if not st or st == "stats" then - stats.init(not not opts["v"]) - build_stats_keyref() - keyref.build() - -- newline if printing what's being generated - printgen() - stats.print() - end - end -} - -return true diff --git a/src/scripts/elua/apps/gendoc.sh b/src/scripts/elua/apps/gendoc.sh deleted file mode 100755 index f14fcfda6e..0000000000 --- a/src/scripts/elua/apps/gendoc.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# a parallel doc generation script -cd "$(dirname "$(realpath "$0")")"; - -# exit on failure -set -e - -gendoc() { - elua gendoc.lua --pass $@ -} - -gendoc rm $@ -gendoc ref $@ - -# limit jobs otherwise stuff starts complaining in eldbus etc -MAXJ=192 - -I=0 -for cl in $(gendoc clist $@); do - gendoc "$cl" $@ & - I=$(($I + 1)) - if [ $I -gt $MAXJ ]; then - I=0 - # wait for the batch to finish - wait - fi -done - -gendoc types $@ & -gendoc vars $@ & - -# wait for all remaining stuff to finish -wait - -# final results -gendoc stats $@ - -exit 0