6 module('classes', package
.seeall
)
8 -- collection of all functions
10 -- collection of bound classes
12 -- list of files to be included
14 -- table of classes by their cname
17 --- Copies functions from the index.
18 function copy_functions(index
)
19 for e
in pairs(index
) do
20 if e
.label
:match
'^Function' then
28 function fix_arguments(index
)
29 for a
in pairs(index
) do
30 if a
.label
=='Argument'
31 and a
.xarg
.default
=='1'
32 and (not string.match(a
.xarg
.defaultvalue
, '^[-+]?%d+%.?%d*[L]?$'))
33 and (not string.match(a
.xarg
.defaultvalue
, '^".*"$'))
34 and a
.xarg
.defaultvalue
~='true'
35 and a
.xarg
.defaultvalue
~='false'
36 and (not string.match(a
.xarg
.defaultvalue
, '^0[xX]%d+$')) then
37 local dv
, call = string.match(a
.xarg
.defaultvalue
, '(.-)(%(%))')
38 dv
= dv
or a
.xarg
.defaultvalue
40 local context
= a
.xarg
.context
41 while not fullnames
[context
..'::'..dv
] and context
~='' do
42 context
= string.match(context
, '^(.*)::') or ''
44 if fullnames
[context
..'::'..dv
] then
45 if fullnames
[context
..'::'..dv
].xarg
.name
==fullnames
[context
..'::'..dv
].xarg
.member_of_class
then
46 context
= string.match(context
, '^(.*)::') or ''
48 a
.xarg
.defaultvalue
= context
..'::'..dv
..call
49 elseif fullnames
[dv
] then
50 a
.xarg
.defaultvalue
= dv
..call
53 a
.xarg
.defaultvalue
= nil
60 --- Removes unneeded 'void' parameters and return values.
61 function fix_functions()
62 for f
in pairs(functions
) do
64 for i
, a
in ipairs(f
) do
65 -- avoid bogus 'void' arguments
66 if a
.xarg
.type_name
=='void' and i
==1 and f
[2]==nil then break end
67 if a
.label
=='Argument' then
72 f
.return_type
= f
.xarg
.type_name
73 if f
.xarg
.type_name
=='void' then
79 --- Determines, if a class is public.
80 function class_is_public(c
)
82 if c
.xarg
.access
~='public' then return false end
83 if c
.xarg
.member_of_class
then
84 local p
= fullnames
[c
.xarg
.member_of_class
]
85 assert(p
, 'member_of_class should exist')
86 assert(p
.label
=='Class', 'member_of_class should be a class')
87 c
= fullnames
[c
.xarg
.member_of_class
]
94 --- Selects public classes from the index, and creates templated instances
96 function copy_classes(index
)
97 for e
in pairs(index
) do
98 if e
.label
=='Class' then
99 e
.xarg
.cname
= string.gsub(e
.xarg
.fullname
, '::', '_LQT_')
100 if class_is_public(e
)
101 and not e
.xarg
.fullname
:match
'%b<>' then
103 elseif not e
.xarg
.fullname
:match
'%b<>' then
104 ignore(e
.xarg
.fullname
, 'not public')
106 if templates
.should_copy(e
) then
107 templates
.create(e
, classes
)
112 templates
.finish(index
)
113 for c
in pairs(classes
) do
114 classlist
[c
.xarg
.cname
] = c
118 function fix_methods_wrappers()
119 for c
in pairs(classes
) do
120 c
.shell
= c
.public_destr
121 c
.shell
= c
.shell
and (next(c
.virtuals
)~=nil)
122 for _
, constr
in ipairs(c
.constructors
) do
124 local shellname
= 'lqt_shell_'..c
.xarg
.cname
125 constr
.calling_line
= 'new '..shellname
..'(L'
126 if #(constr
.arguments
)>0 then constr
.calling_line
= constr
.calling_line
.. ', ' end
128 local shellname
= c
.xarg
.fullname
129 constr
.calling_line
= 'new '..shellname
..'('
131 for i
=1,#(constr
.arguments
) do
132 constr
.calling_line
= constr
.calling_line
.. (i
==1 and '' or ', ') .. 'arg' .. i
134 constr
.calling_line
= '*('..constr
.calling_line
.. '))'
135 constr
.xarg
.static
= '1'
136 constr
.return_type
= constr
.xarg
.scope
..'&'
139 c
.destructor
.return_type
= nil
144 --- Determines, whether classes are children of QObject.
145 -- Fills the 'qobject' field on class if it is child of QObject.
146 function get_qobjects()
147 local function is_qobject(c
)
148 if c
==nil then return false end
149 if c
.qobject
then return true end
150 if c
.xarg
.fullname
=='QObject' then
154 for b
in string.gmatch(c
.xarg
.bases
or '', '([^;]+);') do
155 local base
= fullnames
[b
]
156 if is_qobject(base
) then
157 --debug(c.xarg.fullname, "is a QObject")
164 for c
in pairs(classes
) do
165 local qobj
= is_qobject(c
)
171 local should_wrap
= function(f
)
172 local name
= f
.xarg
.name
173 -- unfixed operator and friend, causes trouble with QDataStream
174 -- if f.xarg.friend and #f.arguments ==2 then return false end
175 -- not an operator - accept
176 if not name
:match('^operator') then return true end
177 -- accept supported operators
178 if operators
.is_operator(name
) then return true end
184 function distinguish_methods()
185 for c
in pairs(classes
) do
186 local construct
, destruct
, normal
= {}, nil, {}
187 local n
= c
.xarg
.name
:gsub('%b<>', '')
190 for _
, f
in ipairs(c
) do
191 if n
==f
.xarg
.name
then
192 table.insert(construct
, f
)
193 elseif f
.xarg
.name
:match
'~' then
197 and (not f
.xarg
.member_template_parameters
) then
198 table.insert(normal
, f
)
200 ignore(f
.xarg
.fullname
, 'operator/template/friend', c
.xarg
.name
)
204 c
.constructors
= construct
205 c
.destructor
= destruct
210 --- Determines, if a class has a public destructor. It also scans the superclasses.
211 -- Sets the 'public_destr' fiield on the class.
212 function fill_public_destr()
213 local function destr_is_public(c
)
215 return c
.destructor
.xarg
.access
=='public'
217 for b
in string.gmatch(c
.xarg
.bases
or '', '([^;]+);') do
218 local base
= fullnames
[b
]
219 if base
and not destr_is_public(base
) then
226 for c
in pairs(classes
) do
227 c
.public_destr
= destr_is_public(c
)
232 function generate_default_copy_constructor(c
)
233 if not c
.xarg
then return end
239 context
= c
.xarg
.name
;
243 type_base
= c
.xarg
.name
;
245 type_name
= c
.xarg
.name
.. " const&";
246 type_reference
= "1";
250 return_type
= c
.xarg
.name
;
253 context
= c
.xarg
.name
;
254 fullname
= c
.xarg
.name
.."::"..c
.xarg
.name
;
257 member_of
= c
.xarg
.name
;
258 member_of_class
= c
.xarg
.name
;
261 type_base
= c
.xarg
.name
;
262 type_name
= c
.xarg
.name
;
265 copy
.arguments
= {copy
[1]}
267 table.insert(c
, copy
)
268 table.insert(c
.constructors
, copy
)
269 functions
[copy
] = true
274 -- HACK: do not create copy contructors for classes, that
275 -- contain variables of class '*Private' - they will not compile
277 local function has_private_fields(c
)
278 for _
,v
in ipairs(c
) do
279 if v
.label
== 'Variable' then
280 if v
.xarg
.type_base
:match('Private') then
281 ignore(c
.xarg
.fullname
, 'cannot create copy constructor', v
.xarg
.fullname
.. ' : ' ..v
.xarg
.type_base
)
289 function fill_copy_constructor()
290 for c
in pairs(classes
) do
292 for _
, f
in ipairs(c
.constructors
) do
294 and f
.arguments
[1].xarg
.type_name
==c
.xarg
.fullname
..' const&' then
299 c
.copy_constructor
= copy
301 local function copy_constr_is_public(c
)
302 if c
.copy_constructor
then
303 return (c
.copy_constructor
.xarg
.access
=='public')
304 or (c
.copy_constructor
.xarg
.access
=='protected')
306 if has_private_fields(c
) then return false end
308 for b
in string.gmatch(c
.xarg
.bases
or '', '([^;]+);') do
309 local base
= fullnames
[b
]
310 if base
and not copy_constr_is_public(base
) then
317 for c
in pairs(classes
) do
318 c
.public_constr
= copy_constr_is_public(c
)
319 if c
.public_constr
and not c
.copy_constructor
then
320 c
.copy_constructor
= generate_default_copy_constructor(c
)
325 function fill_implicit_constructor()
326 typesystem
.can_convert
= {}
327 for c
in pairs(classes
) do
328 for _
,f
in ipairs(c
) do
329 if f
.label
:match("^Function") then
330 -- find non-explicit constructor, which has 1 argument of type different
331 -- from class, i.e. an implicit conversion constructor
332 if f
.xarg
.name
== c
.xarg
.name
334 and (not f
.xarg
.access
or f
.xarg
.access
== "public")
335 and f
[1].xarg
.type_base
~= c
.xarg
.name
336 and not f
[1].xarg
.type_base
:match('Private$')
337 and not f
.xarg
.explicit
340 local class_name
= c
.xarg
.cname
341 local from_type
= f
[1].xarg
.type_base
342 typesystem
.can_convert
[class_name
] = typesystem
.can_convert
[class_name
] or { from
= {}, class
= c
}
343 typesystem
.can_convert
[class_name
].from
[ from_type
] = f
344 local safe_from
= from_type
:gsub('[<>*]', '_'):gsub('::', '_LQT_')
351 local function generate_implicit_code(class_name
, t
)
353 local fullname
= c
.xarg
.fullname
354 local luaname
= fullname
:gsub('::', '.')
356 local test_header
= 'bool lqt_canconvert_' .. class_name
.. '(lua_State *L, int n)'
357 local convert_header
= 'void* lqt_convert_' .. class_name
.. '(lua_State *L, int n)'
360 local convert_code
= ""
363 for _
, f
in pairs(t
.from
) do
364 local typ
= f
[1].xarg
.type_name
365 if not typesystem
[typ
] then
366 ignore(typ
, "implicit constructor - unknown type", _
)
368 local test
= typesystem
[typ
].test('n')
369 if not tests
[test
] then
371 test_code
= test_code
..' if ('..test
..')\n'
372 test_code
= test_code
..' return true;\n'
374 local newtype
= fullname
.. '(arg)'
375 if c
.shell
then newtype
= 'lqt_shell_'..c
.xarg
.cname
..'(L,arg)' end
376 convert_code
= convert_code
377 ..' if ('..test
..') {\n'
378 ..' '..typ
..' arg = '..typesystem
[typ
].get('n')..';\n'
379 ..' '..fullname
..' *ret = new '..newtype
..';\n'
380 ..' lqtL_passudata(L, ret, "'..luaname
..'*");\n'
381 ..' return ret;\n }\n'
385 test_code
= test_code
.. ' return false;'
386 convert_code
= convert_code
..' return NULL;'
389 headers
= { test
= test_header
, convert
= convert_header
},
390 test
= test_header
.. '{\n' .. test_code
.. '\n}',
391 convert
= convert_header
.. '{\n' .. convert_code
.. '\n}'
396 function fill_implicit_wrappers()
397 for class_name
, t
in pairs(typesystem
.can_convert
) do
398 if not t
.class
.abstract
then
399 generate_implicit_code(class_name
, t
)
405 local put_class_in_filesystem
= lqt
.classes
.insert
407 function fill_typesystem_with_classes()
408 for c
in pairs(classes
) do
409 classes
[c
] = put_class_in_filesystem(c
.xarg
.fullname
)
414 function fill_wrapper_code(f
)
415 if f
.wrapper_code
then return f
end
416 local stackn
, argn
= 1, 1
417 local stack_args
, defects
= '', 0
418 local has_args
= true
419 local wrap
, line
= ' int oldtop = lua_gettop(L);\n', ''
420 if f
.xarg
.abstract
then
421 ignore(f
.xarg
.fullname
, 'abstract method', f
.xarg
.member_of_class
)
424 if f
.xarg
.member_of_class
and f
.xarg
.static
~='1' then
425 if not typesystem
[f
.xarg
.member_of_class
..'*'] then
426 ignore(f
.xarg
.fullname
, 'not a member of wrapped class', f
.xarg
.member_of_class
)
429 stack_args
= stack_args
.. typesystem
[f
.xarg
.member_of_class
..'*'].onstack
430 defects
= defects
+ 7 -- FIXME: arbitrary
431 if f
.xarg
.constant
=='1' then
432 defects
= defects
+ 8 -- FIXME: arbitrary
434 local sget
, sn
= typesystem
[f
.xarg
.member_of_class
..'*'].get(stackn
)
435 wrap
= wrap
.. ' ' .. f
.xarg
.member_of_class
.. '* self = ' .. sget
.. ';\n'
439 lua_pushfstring(L, "Instance of %s has already been deleted in:\n", "]]..f
.xarg
.member_of_class
..[[");
446 if operators
.is_operator(f
.xarg
.name
) then
447 line
, has_args
= operators
.call_line(f
)
448 if not line
then return nil end
450 line
= 'self->'..f
.xarg
.fullname
..'('
453 line
= f
.xarg
.fullname
..'('
455 for i
, a
in ipairs(f
.arguments
) do
456 if not typesystem
[a
.xarg
.type_name
] then
457 ignore(f
.xarg
.fullname
, 'unkown argument type', a
.xarg
.type_name
)
460 local aget
, an
, arg_as
= typesystem
[a
.xarg
.type_name
].get(stackn
)
461 stack_args
= stack_args
.. typesystem
[a
.xarg
.type_name
].onstack
462 if typesystem
[a
.xarg
.type_name
].defect
then defects
= defects
+ typesystem
[a
.xarg
.type_name
].defect
end
463 wrap
= wrap
.. ' ' .. argument_name(arg_as
or a
.xarg
.type_name
, 'arg'..argn
) .. ' = '
464 if a
.xarg
.default
=='1' and an
>0 then
465 wrap
= wrap
.. 'lua_isnoneornil(L, '..stackn
..')'
466 for j
= stackn
+1,stackn
+an
-1 do
467 wrap
= wrap
.. ' && lua_isnoneornil(L, '..j
..')'
469 local dv
= a
.xarg
.defaultvalue
470 wrap
= wrap
.. ' ? static_cast< ' .. a
.xarg
.type_name
.. ' >(' .. dv
.. ') : '
472 wrap
= wrap
.. aget
.. ';\n'
473 line
= line
.. (argn
==1 and 'arg' or ', arg') .. argn
480 -- FIXME: hack follows for constructors
481 if f
.calling_line
then line
= f
.calling_line
end
482 if f
.return_type
then line
= f
.return_type
.. ' ret = ' .. line
end
483 wrap
= wrap
.. ' ' .. line
.. ';\n lua_settop(L, oldtop);\n' -- lua_pop(L, '..stackn..');\n'
484 if f
.return_type
then
485 if not typesystem
[f
.return_type
] then
486 ignore(f
.xarg
.fullname
, 'unknown return type', f
.return_type
)
489 local rput
, rn
= typesystem
[f
.return_type
].push
'ret'
490 wrap
= wrap
.. ' luaL_checkstack(L, '..rn
..', "cannot grow stack for return value");\n'
491 wrap
= wrap
.. ' '..rput
..';\n return '..rn
..';\n'
493 wrap
= wrap
.. ' return 0;\n'
495 f
.wrapper_code
= wrap
496 f
.stack_arguments
= stack_args
502 function fill_test_code(f
)
505 if f
.xarg
.member_of_class
and f
.xarg
.static
~='1' then
506 if not typesystem
[f
.xarg
.member_of_class
..'*'] then return nil end -- print(f.xarg.member_of_class) return nil end
507 local stest
, sn
= typesystem
[f
.xarg
.member_of_class
..'*'].test(stackn
)
508 test
= test
.. ' && ' .. stest
511 for i
, a
in ipairs(f
.arguments
) do
512 if not typesystem
[a
.xarg
.type_name
] then return nil end -- print(a.xarg.type_name) return nil end
513 local atest
, an
= typesystem
[a
.xarg
.type_name
].test(stackn
)
514 if a
.xarg
.default
=='1' and an
>0 then
515 test
= test
.. ' && (lqtL_missarg(L, ' .. stackn
.. ', ' .. an
.. ') || '
516 test
= test
.. atest
.. ')'
518 test
= test
.. ' && ' .. atest
522 -- can't make use of default values if I fix number of args
523 test
= '(lua_gettop(L)<' .. stackn
.. ')' .. test
530 function fill_wrappers()
531 for f
in pairs(functions
) do
532 local nf
= fill_wrapper_code(f
)
534 nf
= assert(fill_test_code(nf
), nf
.xarg
.fullname
) -- MUST pass
536 -- failed to generate wrapper
542 ---- Output functions
544 function print_wrappers()
545 for c
in pairs(classes
) do
548 for _
, f
in ipairs(c
.methods
) do
549 -- FIXME: should we really discard virtual functions?
550 -- if the virtual overload in the shell uses rawget
551 -- on the environment then we can leave these in the
553 if f
.wrapper_code
and not f
.ignore
then
554 local out
= 'static int lqt_bind'..f
.xarg
.id
555 ..' (lua_State *L) {\n'.. f
.wrapper_code
.. '}\n'
556 if f
.xarg
.access
=='public' then
558 wrappers
= wrappers
.. out
.. '\n'
559 meta
[f
] = f
.xarg
.name
563 if not c
.abstract
then
564 for _
, f
in ipairs(c
.constructors
) do
565 if f
.wrapper_code
then
566 local out
= 'static int lqt_bind'..f
.xarg
.id
567 ..' (lua_State *L) {\n'.. f
.wrapper_code
.. '}\n'
568 if f
.xarg
.access
=='public' then
570 wrappers
= wrappers
.. out
.. '\n'
576 --local shellname = 'lqt_shell_'..string.gsub(c.xarg.fullname, '::', '_LQT_')
577 local lua_name
= string.gsub(c
.xarg
.fullname
, '::', '.')
578 local out
= 'static int lqt_delete'..c
.xarg
.id
..' (lua_State *L) {\n'
579 out
= out
..' '..c
.xarg
.fullname
..' *p = static_cast<'
580 ..c
.xarg
.fullname
..'*>(lqtL_toudata(L, 1, "'..lua_name
..'*"));\n'
581 if c
.public_destr
then
582 out
= out
.. ' if (p) delete p;\n'
584 out
= out
.. ' lqtL_eraseudata(L, 1, "'..lua_name
..'*");\n return 0;\n}\n'
586 wrappers
= wrappers
.. out
.. '\n'
588 c
.wrappers
= wrappers
593 local print_metatable
= function(c
)
595 local wrappers
= c
.wrappers
596 for m
, n
in pairs(c
.meta
) do
597 methods
[n
] = methods
[n
] or {}
598 table.insert(methods
[n
], m
)
600 for n
, l
in pairs(methods
) do
601 local duplicates
= {}
602 for _
, f
in ipairs(l
) do
605 for sa
, g
in pairs(duplicates
) do
606 if sa
==f
.stack_arguments
then
607 --debug("function equal: ", f.xarg.fullname, f.stack_arguments, sa, f.defects, g.defects)
608 if f
.defects
<g
.defects
then
610 ignore(f
.xarg
.fullname
, "duplicate function", f
.stack_arguments
)
613 elseif string.match(sa
, "^"..f
.stack_arguments
) then -- there is already a version with more arguments
614 --debug("function superseded: ", f.xarg.fullname, f.stack_arguments, sa, f.defects, g.defects)
615 elseif string.match(f
.stack_arguments
, '^'..sa
) then -- there is already a version with less arguments
616 --debug("function superseding: ", f.xarg.fullname, f.stack_arguments, sa, f.defects, g.defects)
620 duplicates
[f
.stack_arguments
] = f
627 for sa, f in pairs(l) do
628 numinitial = numinitial + 1
630 for sa, f in pairs(duplicates) do
631 numfinal = numfinal + 1
633 if numinitial-numfinal>0 then debug(c.xarg.fullname, "suppressed:", numinitial-numfinal) end
635 methods
[n
] = duplicates
637 for n
, l
in pairs(methods
) do
638 local name
= operators
.rename_operator(n
)
639 local disp
= 'static int lqt_dispatcher_'..name
..c
.xarg
.id
..' (lua_State *L) {\n'
641 for tc
, f
in pairs(l
) do
642 disp
= disp
..' if ('..f
.test_code
..') return lqt_bind'..f
.xarg
.id
..'(L);\n'
643 testcode
[#testcode
+1] = tc
645 -- disp = disp .. ' lua_settop(L, 0);\n'
646 disp
= disp
.. ' const char * args = lqtL_getarglist(L);\n'
647 disp
= disp
.. ' lua_pushfstring(L, "%s(%s): incorrect or extra arguments, expecting: %s.", "' ..
648 c
.xarg
.fullname
..'::'..n
..'", args, '..string.format("%q", table.concat(testcode
, ' or ')) .. ');\n'
649 disp
= disp
.. ' return lua_error(L);\n}\n'
651 wrappers
= wrappers
.. disp
.. '\n'
653 local metatable
= 'static luaL_Reg lqt_metatable'..c
.xarg
.id
..'[] = {\n'
654 for n
, l
in pairs(methods
) do
655 local nn
= operators
.rename_operator(n
)
656 metatable
= metatable
.. ' { "'..nn
..'", lqt_dispatcher_'..nn
..c
.xarg
.id
..' },\n'
658 metatable
= metatable
.. ' { "delete", lqt_delete'..c
.xarg
.id
..' },\n'
659 metatable
= metatable
.. ' { 0, 0 },\n};\n'
660 --print_meta(metatable)
661 wrappers
= wrappers
.. metatable
.. '\n'
663 for b
in string.gmatch(c
.xarg
.bases_with_attributes
or '', '([^;]*);') do
664 if not string.match(b
, '^virtual') then
665 b
= string.gsub(b
, '^[^%s]* ', '')
666 bases
= bases
.. ' {"'..string.gsub(b
,'::','.')..'*", (char*)(void*)static_cast<'..b
..'*>(('..c
.xarg
.fullname
..'*)1)-(char*)1},\n'
669 bases
= 'static lqt_Base lqt_base'..c
.xarg
.id
..'[] = {\n'..bases
..' {NULL, 0}\n};\n'
671 wrappers
= wrappers
.. bases
.. '\n'
672 c
.wrappers
= wrappers
677 function print_metatables()
678 for c
in pairs(classes
) do
684 function print_single_class(c
)
685 local n
= c
.xarg
.cname
686 local lua_name
= string.gsub(c
.xarg
.fullname
, '::', '.')
687 local cppname
= module_name
..'_meta_'..n
..'.cpp'
688 table.insert(cpp_files
, n
) -- global cpp_files
689 local fmeta
= assert(io
.open(module_name
.._src
..cppname
, 'w'))
690 local print_meta
= function(...)
694 print_meta('#include "'..module_name
..'_head_'..n
..'.hpp'..'"\n\n')
697 print_meta(c
.implicit
.test
)
698 print_meta(c
.implicit
.convert
)
701 print_meta(c
.wrappers
)
702 if c
.virtual_overloads
then
703 print_meta(c
.virtual_overloads
)
705 print_meta('extern "C" LQT_EXPORT int luaopen_'..n
..' (lua_State *L) {')
706 print_meta('\tlqtL_createclass(L, "'
707 ..lua_name
..'*", lqt_metatable'
708 ..c
.xarg
.id
..', lqt_base'
712 print_meta('\tluaL_getmetatable(L, "'..lua_name
..'*");')
713 print_meta('\tlua_pushliteral(L, "__test");')
714 print_meta('\tlua_pushlightuserdata(L, (void*)&lqt_canconvert_'..c
.xarg
.cname
..');')
715 print_meta('\tlua_rawset(L, -3);')
716 print_meta('\tlua_pushliteral(L, "__convert");')
717 print_meta('\tlua_pushlightuserdata(L, (void*)&lqt_convert_'..c
.xarg
.cname
..');')
718 print_meta('\tlua_rawset(L, -3);')
719 print_meta('\tlua_pop(L, 1);')
722 print_meta
'\treturn 0;'
725 if c
.shell
and c
.qobject
then
729 QMetaObject lqt_shell_]]..n
..[[::staticMetaObject;
731 const QMetaObject *lqt_shell_]]..n
..[[::metaObject() const {
732 //int oldtop = lua_gettop(L);
733 lqtL_pushudata(L, this, "]]..c
.xarg
.fullname
..[[*");
734 lua_getfield(L, -1, LQT_OBJMETASTRING);
735 if (lua_isnil(L, -1)) {
737 return &]]..c
.xarg
.fullname
..[[::staticMetaObject;
739 lua_getfield(L, -2, LQT_OBJMETADATA);
741 //qDebug() << "copying qmeta object for slots in ]]..c
.xarg
.fullname
..[[";
742 lqt_shell_]]..n
..[[::staticMetaObject.d.superdata = &]]..c
.xarg
.fullname
..[[::staticMetaObject;
743 lqt_shell_]]..n
..[[::staticMetaObject.d.stringdata = lua_tostring(L, -2);
744 lqt_shell_]]..n
..[[::staticMetaObject.d.data = (uint*)lua_touserdata(L, -1);
745 lqt_shell_]]..n
..[[::staticMetaObject.d.extradata = 0; // slot_metaobj->d.extradata;
746 lua_setfield(L, LUA_REGISTRYINDEX, LQT_OBJMETADATA);
747 lua_setfield(L, LUA_REGISTRYINDEX, LQT_OBJMETASTRING);
749 //qDebug() << (lua_gettop(L) - oldtop);
750 return &lqt_shell_]]..n
..[[::staticMetaObject;
753 int lqt_shell_]]..n
..[[::qt_metacall(QMetaObject::Call call, int index, void **args) {
754 //qDebug() << "fake calling!";
755 index = ]]..c
.xarg
.fullname
..[[::qt_metacall(call, index, args);
756 if (index < 0) return index;
757 return lqtL_qt_metacall(L, this, lqtSlotAcceptor_]]..module_name
..[[, call, "]]..c
.xarg
.fullname
..[[*", index, args);
764 function print_merged_build()
765 local path
= module_name
.._src
766 local mergename
= module_name
..'_merged_build'
767 local merged
= assert(io
.open(path
..mergename
..'.cpp', 'w'))
768 for _
, p
in ipairs(cpp_files
) do
769 merged
:write('#include "',module_name
,'_head_',p
,'.hpp"\n')
772 for _
, p
in ipairs(cpp_files
) do
773 merged
:write('#include "',module_name
,'_meta_',p
,'.cpp"\n')
775 local pro_file
= assert(io
.open(path
..mergename
..'.pro', 'w'))
777 local print_pro
= function(...)
781 print_pro('TEMPLATE = lib')
782 print_pro('TARGET = '..module_name
)
783 print_pro('INCLUDEPATH += .')
784 print_pro('HEADERS += '..module_name
..'_slot.hpp')
785 print_pro('SOURCES += ../common/lqt_common.cpp \\')
786 print_pro(' ../common/lqt_qt.cpp \\')
787 print_pro(' '..module_name
..'_enum.cpp \\')
788 print_pro(' '..module_name
..'_meta.cpp \\')
789 print_pro(' '..module_name
..'_slot.cpp \\')
790 print_pro(' '..mergename
..'.cpp')
794 function print_class_list()
795 local qobject_present
= false
796 local big_picture
= {}
797 local type_list_t
= {}
798 for c
in pairs(classes
) do
799 local n
= c
.xarg
.cname
800 if n
=='QObject' then qobject_present
= true end
801 print_single_class(c
)
802 table.insert(big_picture
, n
)
803 table.insert(type_list_t
, 'add_class \''..c
.xarg
.fullname
..'\'\n')
806 local type_list_f
= assert(io
.open(module_name
.._src
..module_name
..'_types.lua', 'w'))
809 local types = (...) or {}
810 assert(lqt.classes.insert, 'module lqt.classes not loaded')
811 local function add_class(class)
812 lqt.classes.insert(class, true)
815 for k
, v
in ipairs(type_list_t
) do
818 type_list_f
:write('return types\n')
822 local fmeta
= assert(io
.open(module_name
.._src
..module_name
..'_meta.cpp', 'w'))
823 local print_meta
= function(...)
828 print_meta('#include "lqt_common.hpp"')
829 print_meta('#include "'..module_name
..'_slot.hpp'..'"\n\n')
830 for _
, p
in ipairs(big_picture
) do
831 print_meta('extern "C" LQT_EXPORT int luaopen_'..p
..' (lua_State *);')
833 print_meta('void lqt_create_enums_'..module_name
..' (lua_State *);')
834 print_meta('extern "C" LQT_EXPORT int luaopen_'..module_name
..' (lua_State *L) {')
835 for _
, p
in ipairs(big_picture
) do
836 print_meta('\tluaopen_'..p
..'(L);')
838 print_meta('\tlqt_create_enums_'..module_name
..'(L);')
839 if qobject_present
then
840 print_meta('\tlqtL_qobject_custom(L);')
842 print_meta('\t//lua_pushlightuserdata(L, (void*)&LqtSlotAcceptor::staticMetaObject);')
843 print_meta('\t//lua_setfield(L, LUA_REGISTRYINDEX, LQT_METAOBJECT);')
844 print_meta('\t//lqtL_passudata(L, (void*)(new LqtSlotAcceptor(L)), "QObject*");')
845 print_meta('\t//lua_setfield(L, LUA_REGISTRYINDEX, LQT_METACALLER);')
846 print_meta('\tlqtL_register_super(L);')
847 print_meta('\tlqtSlotAcceptor_'..module_name
..' = new LqtSlotAcceptor(L);')
848 print_meta('\treturn 0;\n}')
849 if fmeta
then fmeta
:close() end
852 ------------------------------------------------------------
854 function preprocess(index
)
855 copy_classes(index
) -- picks classes if not private and not blacklisted
856 copy_functions(index
) -- picks functions and fixes label
857 fix_arguments(index
) -- fixes default arguments if they are context-relative
858 fix_functions() -- fixes name and fullname and fills arguments
859 operators
.fix_operators(index
)
862 function process(index
, typesystem
, filterfiles
)
863 for _
, f
in ipairs(filterfiles
) do
864 classes
= loadfile(f
)(classes
)
867 virtuals
.fill_virtuals(classes
) -- does that, destructor ("~") excluded
868 distinguish_methods() -- does that
869 fill_public_destr() -- does that: checks if destructor is public
870 fill_copy_constructor() -- does that: checks if copy contructor is public or protected
871 fill_implicit_constructor()
872 fix_methods_wrappers()
875 fill_typesystem_with_classes()
877 virtuals
.fill_virtual_overloads(classes
) -- does that
878 virtuals
.fill_shell_classes(classes
) -- does that
879 fill_implicit_wrappers()
881 signalslot
.process(functions
)
885 virtuals
.print_shell_classes(classes
) -- does that, and outputs headers
886 virtuals
.print_virtual_overloads(classes
) -- does that
888 print_wrappers(classes
) -- just compiles metatable list
889 print_metatables(classes
) -- just collects the wrappers + generates dispatchers
890 print_class_list(classes
) -- does that + prints everything related to class