def test_class_method_overload(): cls = cpp.cpp_class('MyTest') cls.qualname = "MyTest" method = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))]) method1 = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True))]) method2 = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True)), cpp.cpp_variable('othervar', cpp.cpp_type('int', const=True))]) cls.public.append(method) method.parent = cls cls.public.append(method1) method1.parent = cls cls.public.append(method2) method2.parent = cls context = lua.lua_context_builder.bake([cls]) assert len(context.translated) == 1 t_cls = context.translated[0] assert t_cls assert t_cls.name == 'lua_munch_MyTest'
def init_translated_method(orig_method, context): assert 'translation' not in orig_method.__dict__ logging.debug('entered [init_translated_method] with method:' + repr(orig_method)) method = cpp.cpp_method('lua_munch_' + orig_method.name, static=True, returns= cpp.cpp_type('int'), params=[cpp.cpp_variable('L', cpp.cpp_type('lua_State', pointer=True))]) if orig_method.is_virtual: method.parameters.append(cpp.cpp_type(orig_method.parent.qualname, pointer= True)) method.public = True #now we embed the default object with a very specific format that will be useful later method.initialization = [] # will contain initialization steps method.validation = [] # will contain validation steps method.recover = [] # will contain the steps to translate the lua arg to a C++ arg method.execution = [] # will contain execution steps, i.e, calling the native method method.lua_return = [] # will contain the steps to push a value back to lua if not 'is_overload' in method.__dict__: method.is_overload = False if orig_method.parent and orig_method.is_virtual: method.parameters.append(cpp.cpp_variable('lua_self', cpp.cpp_type(orig_method.parent.qualname, pointer=True))) if orig_method.is_constructor: method.name = 'lua_munch_' + orig_method.parent.name + '_constructor' method.return_value = cpp.cpp_return(0) #we 'tie' the translated method on the original method #so it's easier to work with them without needing to search for them on every callback orig_method.translation = method
def test_class_base(): base = cpp.cpp_class('base') base.qualname = 'MyBaseClass' bmethod = cpp.cpp_method('base_method', params=[cpp.cpp_variable('variable', cpp.cpp_type('int'))]) bmethod.is_virtual = True base.public.append(bmethod) bmethod.parent = base cls = cpp.cpp_class('MyTest') cls.qualname = 'MyTestClass' cls.bases.append(base) method = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))]) method1 = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('int', const=True))]) cls.public.append(method) method.parent = cls cls.public.append(method1) method1.parent = cls context = lua.lua_context_builder.bake([base, cls]) assert len(context.translated) == 2 t_cls = context.translated[1] assert t_cls assert t_cls.name == 'lua_munch_MyTest' print context.translated[0] print t_cls assert False
def test_method_return(): method = cpp.cpp_method('method', returns=cpp.cpp_type('int'), return_value = 10) context = lua.lua_context_builder.bake([method]) assert len(context.translated) == 1 t_method = context.translated[0] assert t_method.static assert t_method.name == 'lua_munch_method' assert t_method.lua_return
def test_method_1(): method = cpp.cpp_method('method') context = lua.lua_context_builder.bake([method]) assert len(context.translated) == 1 t_method = context.translated[0] assert t_method.static assert t_method.name == 'lua_munch_method' assert not t_method.lua_return
def test_method_param_lua_primitives(): method = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('int'))]) context = lua.lua_context_builder.bake([method]) assert len(context.translated) == 1 t_method = context.translated[0] assert t_method.static assert t_method.name == 'lua_munch_method' assert t_method.initialization assert t_method.initialization[0] assert t_method.initialization[0] == method.parameters[0]
def init_translated_class(orig_class, context): assert 'translation' not in orig_class.__dict__ lua_cls = cpp.cpp_class('lua_munch_' + orig_class.identifier_name) luaReg = cpp.cpp_variable_array('lua_reg_' + orig_class.identifier_name, cpp.cpp_type('luaL_Reg', static=True)) logging.debug('baking methods for class: %s : %s' % (orig_class.name ,orig_class.public)) #we now bake all methods and subclasses from this class, but not preprocess them class_ctx = lua_context_builder.bake(orig_class.public, preprocess=False) for item in class_ctx.translated: if item.public: lua_cls.public.append(item) else: lua_cls.protected.append(item) if type(item) == cpp.cpp_method and not item.is_constructor and item.public: luaReg.expr.append('{ "%s" , lua_munch_%s::lua_munch_%s }' % (item.name, orig_class.name, item.name)) #the base methods are shims that only retrieve it's self and pass it down to the #base class for base in orig_class.bases: for item in base.public: if type(item) != cpp.cpp_method: continue method = cpp.cpp_method('lua_munch_' + item.name, static=True, returns=cpp.cpp_type('int'), params=[cpp.cpp_variable('L', cpp.cpp_type('lua_State', pointer=True))]) if item.parent: item.parameters.append(cpp.cpp_variable('lua_self', cpp.cpp_type(item.parent.name, pointer=True))) method.exprs.append('%s* lua_self = lua_munch_%s::get(L)' % (orig_class.qualname, orig_class.identifier_name)) method.exprs.append(cpp.cpp_return(cpp.cpp_method_call('lua_munch_%s::lua_munch_%s' % (item.parent.name, item.name), params=['L', 'lua_self']))) lua_cls.public.append(method) if not item.is_constructor: luaReg.expr.append('{ "%s" , lua_munch_%s::lua_munch_%s }' % (item.name, orig_class.name, item.name)) luaReg.expr.append('{ 0, 0 }') lua_cls.public.append(luaReg) orig_class.translation = lua_cls
def test_class(): cls = cpp.cpp_class('MyTest') cls.qualname = "MyTest" method = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))]) cls.public.append(method) context = lua.lua_context_builder.bake([cls]) assert len(context.translated) == 1 t_cls = context.translated[0] assert t_cls assert t_cls.name == 'lua_munch_MyTest'
def test_method_param_class(): method = cpp.cpp_method('method', params=[cpp.cpp_variable('myvar', cpp.cpp_type('MyTestClass', const=True))]) var = lua.lua_context_builder.apply_variable_initialization(method.parameters[0], None) assert type(var.ctype) == cpp.cpp_qual_type assert var.ctype.pointer == True context = lua.lua_context_builder.bake([method]) assert len(context.translated) == 1 t_method = context.translated[0] assert t_method.static assert t_method.name == 'lua_munch_method' assert t_method.initialization assert t_method.initialization[0]
def process_functions(cls): overloads = {} for item in cls.public: if type(item) == cpp.cpp_method: if item.name in overloads: overloads[item.name].append(item) else: overloads[item.name] = [item] final_functions = [] overload_count = 0 for func in overloads: #if there is only one function with this name, it's not an overload it safely if len(overloads[func]) == 1: overloads[func][0].is_overload = False final_functions.append(overloads[func][0]) else: newfun = cpp.cpp_method(func) newfun.is_overload = True newfun.overloads = { 'by_arg_count' : [], 'by_lua_type' : [], 'by_cpp_type' : [] } newfun.is_virtual = overloads[func][0].is_virtual newfun.is_constructor = overloads[func][0].is_constructor newfun.parent = cls for i, function in enumerate(overloads[func]): function.name = '%s_overload_%d' % (function.name, overload_count) function.is_overload = False overload_count += 1 #resolving functions that can be deduced by the count of it's arguments same_qnt = False for other_f in overloads[func]: if other_f == function: continue if len(function.parameters) == len(other_f.parameters): same_qnt = True break if not same_qnt: newfun.overloads['by_arg_count'].append(function) continue #resolving functions that can be deduced by the type of it's lua arguments for other_f in overloads[func]: if other_f == function: continue same_basic_types = False for a,b in zip(function.parameters, other_f.parameters): if a.ctype == b.ctype and not is_basic(a): same_basic_types = True break if same_basic_types: break if not same_basic_types: newfun.overloads['by_lua_type'].append(function) continue newfun.overloads['by_cpp_type'].append(function) print repr(newfun), newfun.is_overload final_functions.append(newfun) #filter every final_public = filter(lambda item: type(item) != cpp.cpp_method, cls.public) cls.public = final_public + final_functions print cls.public