elua: remove old lua bindings generator
This commit is contained in:
parent
c493e80c21
commit
a7d475be47
|
@ -1,65 +0,0 @@
|
|||
-- Lualian application
|
||||
-- for use with Elua
|
||||
|
||||
local lualian = require("lualian")
|
||||
local getopt = require("getopt")
|
||||
|
||||
local gen_file = function(opts, i, fname)
|
||||
local printv = opts["v"] and print or function() end
|
||||
printv("Generating for file: " .. fname)
|
||||
local ofile = opts["o"] and opts["o"][i] or nil
|
||||
local fstream = io.stdout
|
||||
if ofile then
|
||||
printv(" Output file: " .. ofile)
|
||||
fstream = io.open(ofile, "w")
|
||||
if not fstream then
|
||||
error("Cannot open output file: " .. ofile)
|
||||
end
|
||||
else
|
||||
printv(" Output file: printing to stdout...")
|
||||
end
|
||||
lualian.generate(fname, fstream)
|
||||
end
|
||||
|
||||
getopt.parse {
|
||||
usage = "Usage: %prog [OPTIONS] file1.eo file2.eo ... fileN.eo",
|
||||
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." },
|
||||
|
||||
{ category = "Generator" },
|
||||
|
||||
{ "I", "include", true, help = "Include a directory.", metavar = "DIR",
|
||||
list = {}
|
||||
},
|
||||
{ "o", "output", true, help = "Specify output file name(s), by "
|
||||
.. "default goes to stdout.",
|
||||
list = {}
|
||||
}
|
||||
},
|
||||
error_cb = function(parser, msg)
|
||||
io.stderr:write(msg, "\n")
|
||||
getopt.help(parser, io.stderr)
|
||||
end,
|
||||
done_cb = function(parser, opts, args)
|
||||
if not opts["h"] then
|
||||
for i, v in ipairs(opts["I"] or {}) do
|
||||
lualian.include_dir(v)
|
||||
end
|
||||
if os.getenv("EFL_RUN_IN_TREE") then
|
||||
lualian.system_directory_add()
|
||||
end
|
||||
lualian.load_eot_files()
|
||||
for i, fname in ipairs(args) do
|
||||
gen_file(opts, i, fname)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
return true
|
|
@ -1,718 +0,0 @@
|
|||
-- Elua lualian module
|
||||
|
||||
local cutil = require("cutil")
|
||||
local util = require("util")
|
||||
local log = require("eina.log")
|
||||
local eolian = require("eolian")
|
||||
|
||||
local M = {}
|
||||
|
||||
local dom
|
||||
|
||||
local type_type = eolian.type_type
|
||||
local class_type = eolian.class_type
|
||||
local func_type = eolian.function_type
|
||||
local obj_scope = eolian.object_scope
|
||||
local param_dir = eolian.parameter_dir
|
||||
|
||||
local gen_unit
|
||||
local gen_state
|
||||
|
||||
local get_state = function()
|
||||
if not gen_state then
|
||||
gen_state = eolian.new()
|
||||
end
|
||||
return assert(gen_state, "could not create eolian state")
|
||||
end
|
||||
|
||||
cutil.init_module(function()
|
||||
dom = log.Domain("lualian")
|
||||
if not dom:is_valid() then
|
||||
log.err("Could not register log domain: lualian")
|
||||
error("Could not register log domain: lualian")
|
||||
end
|
||||
end, function()
|
||||
dom:unregister()
|
||||
dom = nil
|
||||
end)
|
||||
|
||||
local lua_kw = {
|
||||
["and"] = true, ["end"] = true, ["in"] = true, ["local"] = true,
|
||||
["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true,
|
||||
["then"] = true, ["until"] = true
|
||||
}
|
||||
|
||||
local kw_t = function(n)
|
||||
if lua_kw[n] then
|
||||
return n .. "_"
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
local int_builtin = {
|
||||
["byte" ] = true, ["short"] = true, ["int"] = true, ["long"] = true,
|
||||
["llong"] = true,
|
||||
|
||||
["int8" ] = true, ["int16"] = true, ["int32"] = true, ["int64"] = true,
|
||||
["int128"] = true,
|
||||
|
||||
["intptr"] = true
|
||||
}
|
||||
|
||||
local num_others = {
|
||||
["size" ] = true, ["ssize" ] = true, ["ptrdiff"] = true,
|
||||
["float"] = true, ["double"] = true
|
||||
}
|
||||
|
||||
local is_num = function(x)
|
||||
if not x then
|
||||
return false
|
||||
end
|
||||
if num_others [x ] then return true end
|
||||
if int_builtin[x ] then return true end
|
||||
if int_builtin["u" .. x] then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
local known_out = {
|
||||
["Evas_Coord"] = function(expr) return ("tonumber(%s)"):format(expr) end,
|
||||
["bool"] = function(expr) return ("((%s) ~= 0)"):format(expr) end,
|
||||
["char"] = function(expr) return ("string.char(%s)"):format(expr) end
|
||||
}
|
||||
|
||||
local known_in = {
|
||||
["Evas_Coord"] = function(expr) return expr end,
|
||||
["bool"] = function(expr) return expr end
|
||||
}
|
||||
|
||||
local known_ptr_out = {
|
||||
["const char"] = function(expr) return ("ffi.string(%s)"):format(expr) end
|
||||
}
|
||||
|
||||
local known_ptr_in = {
|
||||
["const char"] = function(expr) return expr end
|
||||
}
|
||||
|
||||
local convfuncs = {}
|
||||
|
||||
local build_calln = function(tps, expr, isin)
|
||||
return expr
|
||||
end
|
||||
|
||||
local typeconv = function(tps, expr, isin)
|
||||
if tps:type_get() == type_type.POINTER then
|
||||
local base = tps:base_type_get()
|
||||
local f = (isin and known_ptr_in or known_ptr_out)[base:c_type_get(eolian.c_type_type.DEFAULT)]
|
||||
if f then return f(expr) end
|
||||
return build_calln(tps, expr, isin)
|
||||
end
|
||||
|
||||
local tp = tps:short_name_get()
|
||||
|
||||
if is_num(tp) then
|
||||
return isin and expr or ("tonumber(%s)"):format(expr)
|
||||
end
|
||||
|
||||
local f = (isin and known_in or known_out)[tp]
|
||||
if f then
|
||||
return f(expr)
|
||||
end
|
||||
|
||||
return build_calln(tps, expr, isin)
|
||||
end
|
||||
|
||||
local Node = util.Object:clone {
|
||||
generate = function(self, s)
|
||||
end,
|
||||
|
||||
gen_children = function(self, s)
|
||||
local len = #self.children
|
||||
|
||||
local evs = self.events
|
||||
local evslen
|
||||
if evs then evslen = #evs end
|
||||
local hasevs = evs and evslen > 0
|
||||
|
||||
local hasprops = false
|
||||
local nprops = 0
|
||||
local props = {}
|
||||
|
||||
for i, v in ipairs(self.children) do
|
||||
v.parent_node = self
|
||||
if v.generate_prop then
|
||||
if v:generate_prop(props) then
|
||||
nprops = nprops + 1
|
||||
end
|
||||
hasprops = true
|
||||
end
|
||||
v:generate(s, (not hasevs) and (not hasprops) and (i == len))
|
||||
end
|
||||
|
||||
if hasevs then
|
||||
s:write(" __events = {\n")
|
||||
for i, v in ipairs(evs) do
|
||||
v.parent_node = self
|
||||
v:generate(s, i == evslen)
|
||||
end
|
||||
s:write(" }", hasprops and "," or "", "\n")
|
||||
end
|
||||
|
||||
if hasprops then
|
||||
if hasevs then
|
||||
s:write("\n")
|
||||
end
|
||||
s:write(" __properties = {\n")
|
||||
local pi = 0
|
||||
for k, v in pairs(props) do
|
||||
pi = pi + 1
|
||||
s:write(" [\"", k, "\"] = { ", table.concat(v, ", "),
|
||||
" }", pi ~= nprops and "," or "", "\n")
|
||||
end
|
||||
s:write(" }\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local Method = Node:clone {
|
||||
__ctor = function(self, meth)
|
||||
self.method = meth
|
||||
end,
|
||||
|
||||
gen_proto = function(self)
|
||||
if self.cached_proto then return self.cached_proto end
|
||||
|
||||
local meth = self.method
|
||||
local pars = meth:parameters_get()
|
||||
local rett = meth:return_type_get(func_type.METHOD)
|
||||
|
||||
local proto = {
|
||||
name = meth:name_get()
|
||||
}
|
||||
proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void"
|
||||
local args, cargs, vargs = { "self" }, {}, {}
|
||||
proto.args, proto.cargs, proto.vargs = args, cargs, vargs
|
||||
local rets = {}
|
||||
proto.rets = rets
|
||||
local allocs = {}
|
||||
proto.allocs = allocs
|
||||
|
||||
proto.full_name = meth:full_c_name_get(func_type.METHOD)
|
||||
|
||||
local fulln = proto.full_name
|
||||
|
||||
if rett then
|
||||
rets[#rets + 1] = typeconv(rett, "v", false)
|
||||
end
|
||||
|
||||
for v in pars do
|
||||
local dir, tps, nm = v:direction_get(), v:type_get(), kw_t(v:name_get())
|
||||
local tp = tps:c_type_get(eolian.c_type_type.PARAM)
|
||||
if dir == param_dir.OUT or dir == param_dir.INOUT then
|
||||
if dir == param_dir.INOUT then
|
||||
args[#args + 1] = nm
|
||||
end
|
||||
cargs [#cargs + 1] = tp .. " *" .. nm
|
||||
vargs [#vargs + 1] = nm
|
||||
allocs[#allocs + 1] = { tp, nm, (dir == param_dir.INOUT)
|
||||
and typeconv(tps, nm, true) or nil }
|
||||
rets [#rets + 1] = typeconv(tps, nm .. "[0]", false)
|
||||
else
|
||||
args [#args + 1] = nm
|
||||
cargs [#cargs + 1] = tp .. " " .. nm
|
||||
vargs [#vargs + 1] = typeconv(tps, nm, true)
|
||||
end
|
||||
end
|
||||
|
||||
if #cargs == 0 then cargs[1] = "void" end
|
||||
|
||||
self.cached_proto = proto
|
||||
|
||||
return proto
|
||||
end,
|
||||
|
||||
generate = function(self, s, last)
|
||||
local proto = self:gen_proto()
|
||||
s:write(" ", proto.name, proto.suffix or "", " = function(",
|
||||
table.concat(proto.args, ", "), ")\n")
|
||||
s:write( " eo.__do_start(self, __class)\n")
|
||||
for i, v in ipairs(proto.allocs) do
|
||||
s:write(" local ", v[2], " = ffi.new(\"", v[1], "[1]\")\n")
|
||||
end
|
||||
local genv = (proto.ret_type ~= "void")
|
||||
s:write(" ", genv and "local v = " or "", "__lib.",
|
||||
proto.full_name, "(", table.concat(proto.vargs, ", "), ")\n")
|
||||
s:write(" eo.__do_end()\n")
|
||||
if #proto.rets > 0 then
|
||||
s:write(" return ", table.concat(proto.rets, ", "), "\n")
|
||||
end
|
||||
s:write(" end", last and "" or ",", last and "\n" or "\n\n")
|
||||
end,
|
||||
|
||||
gen_ffi = function(self, s)
|
||||
local proto = self:gen_proto()
|
||||
local ret = proto.ret_type
|
||||
if ret:match("[a-zA-Z0-9_]$") then
|
||||
ret = ret .. " "
|
||||
end
|
||||
local cproto = {
|
||||
" ", ret, proto.full_name, "(", table.concat(proto.cargs, ", "),
|
||||
");\n"
|
||||
}
|
||||
s:write(table.concat(cproto))
|
||||
end
|
||||
}
|
||||
|
||||
local Property = Method:clone {
|
||||
__ctor = function(self, prop, ftype)
|
||||
self.property = prop
|
||||
self.isget = (ftype == func_type.PROP_GET)
|
||||
self.ftype = ftype
|
||||
end,
|
||||
|
||||
gen_proto = function(self)
|
||||
if self.cached_proto then return self.cached_proto end
|
||||
|
||||
local prop = self.property
|
||||
local keys = prop:property_keys_get(self.ftype):to_array()
|
||||
local vals = prop:property_values_get(self.ftype):to_array()
|
||||
local rett = prop:return_type_get(self.ftype)
|
||||
|
||||
local proto = {
|
||||
name = prop:name_get(),
|
||||
suffix = (self.isget and "_get" or "_set"),
|
||||
nkeys = #keys,
|
||||
nvals = #vals
|
||||
}
|
||||
proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void"
|
||||
local args, cargs, vargs = { "self" }, {}, {}
|
||||
proto.args, proto.cargs, proto.vargs = args, cargs, vargs
|
||||
local rets = {}
|
||||
proto.rets = rets
|
||||
local allocs = {}
|
||||
proto.allocs = allocs
|
||||
|
||||
proto.full_name = prop:full_c_name_get(self.ftype)
|
||||
|
||||
local fulln = proto.full_name
|
||||
if #keys > 0 then
|
||||
for i, v in ipairs(keys) do
|
||||
local nm = kw_t(v:name_get())
|
||||
local tps = v:type_get()
|
||||
local tp = tps:c_type_get(eolian.c_type_type.PARAM)
|
||||
args [#args + 1] = nm
|
||||
cargs[#cargs + 1] = tp .. " " .. nm
|
||||
vargs[#vargs + 1] = typeconv(tps, nm, true)
|
||||
end
|
||||
end
|
||||
proto.kprop = #keys > 0
|
||||
|
||||
if #vals > 0 then
|
||||
if self.isget then
|
||||
if #vals == 1 and not rett then
|
||||
local tps = vals[1]:type_get()
|
||||
proto.ret_type = tps:c_type_get(eolian.c_type_type.PARAM)
|
||||
rets[#rets + 1] = typeconv(tps, "v", false)
|
||||
else
|
||||
for i, v in ipairs(vals) do
|
||||
local dir, tps, nm = v:direction_get(), v:type_get(),
|
||||
kw_t(v:name_get())
|
||||
local tp = tps:c_type_get(eolian.c_type_type.PARAM)
|
||||
cargs [#cargs + 1] = tp .. " *" .. nm
|
||||
vargs [#vargs + 1] = nm
|
||||
allocs[#allocs + 1] = { tp, nm }
|
||||
rets [#rets + 1] = typeconv(tps, nm .. "[0]", false)
|
||||
end
|
||||
end
|
||||
else
|
||||
for i, v in ipairs(vals) do
|
||||
local dir, tps, nm = v:direction_get(), v:type_get(),
|
||||
kw_t(v:name_get())
|
||||
local tp = tps:c_type_get(eolian.c_type_type.PARAM)
|
||||
args [#args + 1] = nm
|
||||
cargs[#cargs + 1] = tp .. " " .. nm
|
||||
vargs[#vargs + 1] = typeconv(tps, nm, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #cargs == 0 then cargs[1] = "void" end
|
||||
|
||||
self.cached_proto = proto
|
||||
|
||||
return proto
|
||||
end,
|
||||
|
||||
generate_prop = function(self, props)
|
||||
local proto = self:gen_proto()
|
||||
local prop = props[proto.name]
|
||||
local hasprop = true
|
||||
if not prop then
|
||||
prop = { 0, 0, 0, 0, "false", "false" }
|
||||
props[proto.name] = prop
|
||||
hasprop = false
|
||||
end
|
||||
if self.isget then
|
||||
prop[1] = proto.nkeys
|
||||
prop[3] = math.max(proto.nvals, 1)
|
||||
prop[5] = "true"
|
||||
else
|
||||
prop[2] = proto.nkeys
|
||||
prop[4] = math.max(proto.nvals, 1)
|
||||
prop[6] = "true"
|
||||
end
|
||||
return not hasprop
|
||||
end
|
||||
}
|
||||
|
||||
local Event = Node:clone {
|
||||
__ctor = function(self, ename, etype, ecname)
|
||||
self.ename = ename
|
||||
self.etype = etype
|
||||
self.ecname = ecname
|
||||
end,
|
||||
|
||||
generate = function(self, s, last)
|
||||
s:write(" [\"", self.ename, "\"] = __lib.",
|
||||
"_" .. self.ecname, last and "\n" or ",\n")
|
||||
end,
|
||||
|
||||
gen_ffi = function(self, s)
|
||||
s:write(" extern const Eo_Event_Description ",
|
||||
"_" .. self.ecname, ";\n")
|
||||
end
|
||||
}
|
||||
|
||||
local gen_ns = function(klass, s)
|
||||
local nspaces = klass:namespaces_get():to_array()
|
||||
if #nspaces > 1 then
|
||||
local lnspaces = {}
|
||||
for i = 2, #nspaces do
|
||||
lnspaces[i - 1] = '"' .. nspaces[i]:lower() .. '"'
|
||||
end
|
||||
s:write("local __M = util.get_namespace(M, { ",
|
||||
table.concat(lnspaces, ", "), " })\n")
|
||||
return "__M"
|
||||
else
|
||||
return "M"
|
||||
end
|
||||
end
|
||||
|
||||
local Mixin = Node:clone {
|
||||
__ctor = function(self, iface, klass, ch, evs)
|
||||
self.klass = klass
|
||||
self.children = ch
|
||||
self.events = evs
|
||||
self.iface = iface
|
||||
end,
|
||||
|
||||
generate = function(self, s)
|
||||
dom:log(log.level.INFO, " Generating for interface/mixin: "
|
||||
.. self.klass:name_get())
|
||||
|
||||
s:write("ffi.cdef [[\n")
|
||||
self:gen_ffi(s)
|
||||
s:write("]]\n\n")
|
||||
|
||||
gen_ns(self.klass, s)
|
||||
|
||||
s:write("__body = {\n")
|
||||
self:gen_children(s)
|
||||
s:write("}\n")
|
||||
|
||||
local knu = self.klass:name_get():gsub("%.", "_")
|
||||
if not self.iface then
|
||||
s:write(("__body[\"__mixin_%s\"] = true\n"):format(knu))
|
||||
else
|
||||
s:write(("__body[\"__iface_%s\"] = true\n"):format(knu))
|
||||
end
|
||||
end,
|
||||
|
||||
gen_ffi = function(self, s)
|
||||
s:write(" const Eo_Class *", self.klass:c_get_function_name_get(),
|
||||
"(void);\n")
|
||||
for i, v in ipairs(self.children) do
|
||||
v.parent_node = self
|
||||
v:gen_ffi(s)
|
||||
end
|
||||
if self.events then
|
||||
for i, v in ipairs(self.events) do
|
||||
v.parent_node = self
|
||||
v:gen_ffi(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local build_pn = function(fn, pn)
|
||||
if fn == pn then
|
||||
return kw_t(pn)
|
||||
end
|
||||
return fn .. "_" .. pn
|
||||
end
|
||||
|
||||
local Class = Node:clone {
|
||||
__ctor = function(self, klass, parents, mixins, ch, evs)
|
||||
self.klass = klass
|
||||
self.parents = parents
|
||||
self.interfaces = interfaces
|
||||
self.mixins = mixins
|
||||
self.children = ch
|
||||
self.events = evs
|
||||
end,
|
||||
|
||||
generate = function(self, s)
|
||||
dom:log(log.level.INFO, " Generating for class: "
|
||||
.. self.klass:name_get())
|
||||
|
||||
s:write("ffi.cdef [[\n")
|
||||
self:gen_ffi(s)
|
||||
s:write("]]\n\n")
|
||||
|
||||
local mname = gen_ns(self.klass, s)
|
||||
|
||||
s:write("__body = {\n")
|
||||
self:gen_ctor(s)
|
||||
self:gen_children(s)
|
||||
s:write("}\n")
|
||||
|
||||
-- write the constructor
|
||||
s:write(([[
|
||||
|
||||
%s.%s = function(parent, ...)
|
||||
return eo.__ctor_common(__class, parent, eo.class_get("%s").__eo_ctor,
|
||||
1, ...)
|
||||
end
|
||||
]]):format(mname, self.klass:short_name_get(), self.klass:name_get():gsub("%.",
|
||||
"_")))
|
||||
end,
|
||||
|
||||
gen_ffi = Mixin.gen_ffi,
|
||||
|
||||
gen_ctor = function(self, s)
|
||||
local ctors = self.klass:constructors_get()
|
||||
if not ctors then return end
|
||||
-- collect constructor information
|
||||
s:write(" __eo_ctor = function(self, ")
|
||||
local cfuncs, parnames, upars = {}, {}, {}
|
||||
for ctor in ctors do
|
||||
local cfunc = ctor:function_get()
|
||||
local cn = cfunc:name_get()
|
||||
local tp = cfunc:type_get()
|
||||
if tp == func_type.PROPERTY or tp == func_type.PROP_SET
|
||||
or tp == func_type.METHOD then
|
||||
cfuncs[#cfuncs + 1] = cfunc
|
||||
if tp ~= func_type.METHOD then
|
||||
for par in cfunc:property_keys_get(func_type.PROP_SET) do
|
||||
parnames[#parnames + 1] = build_pn(cn, par:name_get())
|
||||
end
|
||||
end
|
||||
local iter = (tp ~= func_type.METHOD)
|
||||
and cfunc:property_values_get(func_type.PROP_SET)
|
||||
or cfunc:parameters_get()
|
||||
for par in iter do
|
||||
if par:direction_get() ~= param_dir.OUT then
|
||||
parnames[#parnames + 1] = build_pn(cn, par:name_get())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
s:write(table.concat(parnames, ", "))
|
||||
if #parnames == 0 then
|
||||
s:write("__func")
|
||||
else
|
||||
s:write(", __func")
|
||||
end
|
||||
s:write(")\n")
|
||||
-- write ctor body
|
||||
local j = 1
|
||||
for i, cfunc in ipairs(cfuncs) do
|
||||
local tp = cfunc:type_get()
|
||||
s:write(" self:", cfunc:name_get())
|
||||
if cfunc:type_get() ~= func_type.METHOD then
|
||||
s:write("_set")
|
||||
end
|
||||
s:write("(")
|
||||
local fpars = {}
|
||||
if tp ~= func_type.METHOD then
|
||||
for par in cfunc:property_keys_get(func_type.PROP_SET) do
|
||||
fpars[#fpars + 1] = parnames[j]
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
local iter = (tp ~= func_type.METHOD)
|
||||
and cfunc:property_values_get(func_type.PROP_SET)
|
||||
or cfunc:parameters_get()
|
||||
for par in iter do
|
||||
if par:direction_get() ~= param_dir.OUT then
|
||||
fpars[#fpars + 1] = parnames[j]
|
||||
j = j + 1
|
||||
end
|
||||
end
|
||||
s:write(table.concat(fpars, ", "))
|
||||
s:write(")\n")
|
||||
end
|
||||
s:write(" if __func then __func() end\n")
|
||||
s:write(" end")
|
||||
if #self.children > 0 then
|
||||
s:write(",\n\n")
|
||||
else
|
||||
s:write("\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local File = Node:clone {
|
||||
__ctor = function(self, fname, klass, ch)
|
||||
self.fname = fname:match(".+/(.+)") or fname
|
||||
self.klass = klass
|
||||
self.children = ch
|
||||
end,
|
||||
|
||||
generate = function(self, s)
|
||||
local kls = self.klass
|
||||
local ckls = self.children[1]
|
||||
|
||||
local kn = kls:name_get()
|
||||
|
||||
dom:log(log.level.INFO, "Generating for file: " .. self.fname)
|
||||
dom:log(log.level.INFO, " Class : " .. kn)
|
||||
|
||||
local knu = kn:gsub("%.", "_")
|
||||
|
||||
local pars = ckls.parents or {}
|
||||
local mins = ckls.mixins or {}
|
||||
|
||||
-- serialize both
|
||||
local pv = {}
|
||||
local mv = {}
|
||||
for i = 1, #pars do pv[i] = '"' .. pars[i]:gsub("%.", "_") .. '"' end
|
||||
for i = 1, #mins do mv[i] = '"' .. mins[i]:gsub("%.", "_") .. '"' end
|
||||
pars = (#pars > 0) and ("{" .. table.concat(pv, ", ") .. "}") or "nil"
|
||||
mins = (#mins > 0) and ("{" .. table.concat(mv, ", ") .. "}") or "nil"
|
||||
|
||||
s:write(([[
|
||||
-- EFL LuaJIT bindings: %s (class %s)
|
||||
-- For use with Elua; automatically generated, do not modify
|
||||
|
||||
local cutil = require("cutil")
|
||||
local util = require("util")
|
||||
local ffi = require("ffi")
|
||||
local eo = require("eo")
|
||||
|
||||
local M, __lib = ...
|
||||
|
||||
local __class
|
||||
local __body
|
||||
|
||||
local init = function()
|
||||
__class = __lib.%s()
|
||||
eo.class_register("%s", %s, %s, __body, __class)
|
||||
end
|
||||
|
||||
cutil.init_module(init, function() end)
|
||||
|
||||
]]):format(self.fname, kn, kls:c_get_function_name_get(), knu, pars, mins))
|
||||
|
||||
self:gen_children(s)
|
||||
|
||||
s:write([[
|
||||
|
||||
return M
|
||||
]])
|
||||
|
||||
local first = true
|
||||
for name, v in pairs(convfuncs) do
|
||||
if first then
|
||||
print("\nRequired conversion functions:")
|
||||
first = false
|
||||
end
|
||||
print(" " .. name)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local gen_contents = function(klass)
|
||||
local cnt = {}
|
||||
-- first try properties
|
||||
local props = klass:functions_get(func_type.PROPERTY):to_array()
|
||||
for i, v in ipairs(props) do
|
||||
local gscope = v:scope_get(func_type.PROP_GET)
|
||||
local sscope = v:scope_get(func_type.PROP_SET)
|
||||
if (gscope == obj_scope.PUBLIC or sscope == obj_scope.PUBLIC) then
|
||||
local ftype = v:type_get()
|
||||
local fread = (ftype == func_type.PROPERTY or ftype == func_type.PROP_GET)
|
||||
local fwrite = (ftype == func_type.PROPERTY or ftype == func_type.PROP_SET)
|
||||
if fwrite and sscope == obj_scope.PUBLIC then
|
||||
cnt[#cnt + 1] = Property(v, func_type.PROP_SET)
|
||||
end
|
||||
if fread and gscope == obj_scope.PUBLIC then
|
||||
cnt[#cnt + 1] = Property(v, func_type.PROP_GET)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- then methods
|
||||
local meths = klass:functions_get(func_type.METHOD):to_array()
|
||||
for i, v in ipairs(meths) do
|
||||
if v:scope_get(func_type.METHOD) == obj_scope.PUBLIC then
|
||||
cnt[#cnt + 1] = Method(v)
|
||||
end
|
||||
end
|
||||
-- events
|
||||
local evs = {}
|
||||
local events = klass:events_get():to_array()
|
||||
for i, v in ipairs(events) do
|
||||
evs[#evs + 1] = Event(v:name_get(), v:type_get(), v:c_name_get())
|
||||
end
|
||||
return cnt, evs
|
||||
end
|
||||
|
||||
local gen_class = function(klass)
|
||||
local tp = klass:type_get()
|
||||
if tp == class_type.UNKNOWN then
|
||||
error(klass:name_get() .. ": unknown type")
|
||||
elseif tp == class_type.MIXIN or tp == class_type.INTERFACE then
|
||||
return Mixin(tp == class_type.INTERFACE, klass, gen_contents(klass))
|
||||
end
|
||||
local inherits = klass:inherits_get():to_array()
|
||||
-- figure out the correct lookup order
|
||||
local parents = {}
|
||||
local mixins = {} -- also includes ifaces, they're separated later
|
||||
for i = 1, #inherits do
|
||||
local tp = inherits[i]:type_get()
|
||||
if tp == class_type.REGULAR or tp == class_type.ABSTRACT then
|
||||
parents[#parents + 1] = v
|
||||
elseif tp == class_type.INTERFACE or tp == class_type.MIXIN then
|
||||
mixins[#mixins + 1] = v
|
||||
else
|
||||
error(klass:name_get() .. ": unknown inherit " .. v)
|
||||
end
|
||||
end
|
||||
return Class(klass, parents, mixins, gen_contents(klass))
|
||||
end
|
||||
|
||||
M.include_dir = function(dir)
|
||||
if not get_state():directory_add(dir) then
|
||||
error("Failed including directory: " .. dir)
|
||||
end
|
||||
end
|
||||
|
||||
M.load_eot_files = function()
|
||||
return get_state():all_eot_files_parse()
|
||||
end
|
||||
|
||||
M.system_directory_add = function()
|
||||
return get_state():system_directory_add()
|
||||
end
|
||||
|
||||
M.generate = function(fname, fstream)
|
||||
local unit = get_state():file_parse(fname)
|
||||
if unit == nil then
|
||||
error("Failed parsing file: " .. fname)
|
||||
end
|
||||
gen_unit = unit
|
||||
local sfn = fname:match(".*[\\/](.+)$") or fname
|
||||
local klass = get_state():class_by_file_get(sfn)
|
||||
File(fname, klass, { gen_class(klass) }):generate(fstream or io.stdout)
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in New Issue