Skip to content

Commit 4e65bc7

Browse files
authored
Merge pull request #116 from LuaAndC/improve-AB.py
automate_bindings.py: comments on function groups
2 parents 2f82d97 + a8c9b4f commit 4e65bc7

File tree

2 files changed

+109
-82
lines changed

2 files changed

+109
-82
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ branches:
1919
before_install:
2020
- sudo apt-get update
2121
- sudo apt-get install --yes gccxml libwt-dev libwthttp-dev libwttest-dev libyaml-dev
22-
- sudo pip install cpp-coveralls
22+
- sudo pip install -U cpp-coveralls
2323
- sudo pip install hererocks
2424
- sudo pip install pygccxml
2525
- sudo pip install pyyaml

tools/automate_bindings.py

Lines changed: 108 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
XML_CACHE = 'src/luawt/xml'
4242
INCLUDE_WT = '/usr/include/Wt'
4343

44+
# =============================================================================
45+
# Loading/parsing functions: parse, loadAdditionalChunk.
46+
# Get namespace object by the filename / module name.
47+
4448
def parse(filename, include_paths=None):
4549
# Make sure Wt is installed to correct directory.
4650
wconfigh = '%s/WConfig.h' % INCLUDE_WT
@@ -76,6 +80,9 @@ def loadAdditionalChunk(module_str):
7680
else:
7781
raise Exception('Unable to load module called %s' % module_str)
7882

83+
# =============================================================================
84+
# Utility functions to transform or extract types/declarations or to get some info about them.
85+
7986
def isTemplate(method_name, decl_obj, namespace):
8087
# Luawt doesn't support C++ templates.
8188
if pygccxml.declarations.templates.is_instantiation(str(decl_obj)):
@@ -139,65 +146,6 @@ def isBaseOrItsDescendant(child, base_name, Wt):
139146
return True
140147
return False
141148

142-
def checkArgumentType(method_name, arg_type, Wt):
143-
if isTemplate(method_name, arg_type, Wt):
144-
return False
145-
# Is built-in or problematic
146-
if getBuiltinType(str(arg_type)):
147-
# Is problematic
148-
if findCorrespondingKeyInDict(
149-
PROBLEMATIC_TO_BUILTIN_CONVERSIONS,
150-
str(arg_type),
151-
):
152-
if pygccxml.declarations.is_reference(arg_type):
153-
if isConstReference(arg_type):
154-
return True
155-
elif not pygccxml.declarations.is_pointer(arg_type):
156-
return True
157-
# Is built-in
158-
else:
159-
if not pygccxml.declarations.is_pointer(arg_type):
160-
if not pygccxml.declarations.is_reference(arg_type):
161-
return True
162-
elif isBaseOrItsDescendant(clearType(arg_type), 'WWidget', Wt):
163-
if not pygccxml.declarations.is_pointer(arg_type):
164-
logging.info(
165-
'Argument of method %s has strange type %s',
166-
method_name,
167-
arg_type,
168-
)
169-
return True
170-
logging.warning(
171-
'Its impossible to bind method %s: its arg has type %s',
172-
method_name,
173-
arg_type,
174-
)
175-
return False
176-
177-
def checkReturnType(method_name, raw_return_type, Wt):
178-
# Special cases.
179-
if isTemplate(method_name, raw_return_type, Wt):
180-
return False
181-
if str(raw_return_type) == 'void':
182-
return True
183-
# Built-in or problematic return type.
184-
if getBuiltinType(str(raw_return_type)):
185-
if isConstReference(raw_return_type):
186-
return True
187-
elif not pygccxml.declarations.is_pointer(raw_return_type):
188-
return True
189-
elif isBaseOrItsDescendant(clearType(raw_return_type), 'WWidget', Wt):
190-
if pygccxml.declarations.is_pointer(raw_return_type):
191-
return True
192-
elif isConstReference(raw_return_type):
193-
return True
194-
logging.warning(
195-
'Its impossible to bind method %s: of its return type %s',
196-
method_name,
197-
raw_return_type,
198-
)
199-
return False
200-
201149
def getInternalNamespace(decl_str):
202150
chunks = decl_str.split('::')
203151
if len(chunks) == 2:
@@ -217,7 +165,7 @@ def enumObjFromNamespace(enum_str, namespace):
217165
def getEnumObj(enum_str, default_namespace):
218166
chunks = enum_str.split('::')
219167
if len(chunks) == 2:
220-
# Namespace::Enum --> Enum
168+
# Namespace::Enum --> Enum.
221169
enum_str = chunks[1]
222170
enum_obj = enumObjFromNamespace(enum_str, default_namespace)
223171
if not enum_obj:
@@ -268,10 +216,73 @@ def addEnum(type_obj, namespace):
268216
GLOBAL_ENUMS_REGISTRY[type_str][1].sort()
269217

270218
def getArgType(arg):
271-
# For compatibility with pygccxml v1.7.1
219+
# For compatibility with pygccxml v1.7.1.
272220
arg_field = hasattr(arg, 'decl_type') and arg.decl_type or arg.type
273221
return arg_field
274222

223+
# =============================================================================
224+
# Checker functions: checkArgumentType, checkReturnType and checkWtFunction.
225+
# They do check that current version of luawt supports them.
226+
227+
def checkArgumentType(method_name, arg_type, Wt):
228+
if isTemplate(method_name, arg_type, Wt):
229+
return False
230+
# Is built-in or problematic.
231+
if getBuiltinType(str(arg_type)):
232+
# Is problematic.
233+
if findCorrespondingKeyInDict(
234+
PROBLEMATIC_TO_BUILTIN_CONVERSIONS,
235+
str(arg_type),
236+
):
237+
if pygccxml.declarations.is_reference(arg_type):
238+
if isConstReference(arg_type):
239+
return True
240+
elif not pygccxml.declarations.is_pointer(arg_type):
241+
return True
242+
# Is built-in.
243+
else:
244+
if not pygccxml.declarations.is_pointer(arg_type):
245+
if not pygccxml.declarations.is_reference(arg_type):
246+
return True
247+
elif isBaseOrItsDescendant(clearType(arg_type), 'WWidget', Wt):
248+
if not pygccxml.declarations.is_pointer(arg_type):
249+
logging.info(
250+
'Argument of method %s has strange type %s',
251+
method_name,
252+
arg_type,
253+
)
254+
return True
255+
logging.warning(
256+
'Its impossible to bind method %s: its arg has type %s',
257+
method_name,
258+
arg_type,
259+
)
260+
return False
261+
262+
def checkReturnType(method_name, raw_return_type, Wt):
263+
# Special cases.
264+
if isTemplate(method_name, raw_return_type, Wt):
265+
return False
266+
if str(raw_return_type) == 'void':
267+
return True
268+
# Built-in or problematic return type.
269+
if getBuiltinType(str(raw_return_type)):
270+
if isConstReference(raw_return_type):
271+
return True
272+
elif not pygccxml.declarations.is_pointer(raw_return_type):
273+
return True
274+
elif isBaseOrItsDescendant(clearType(raw_return_type), 'WWidget', Wt):
275+
if pygccxml.declarations.is_pointer(raw_return_type):
276+
return True
277+
elif isConstReference(raw_return_type):
278+
return True
279+
logging.warning(
280+
'Its impossible to bind method %s: of its return type %s',
281+
method_name,
282+
raw_return_type,
283+
)
284+
return False
285+
275286
def checkWtFunction(is_constructor, func, Wt):
276287
if func.access_type != 'public':
277288
return False
@@ -287,6 +298,9 @@ def checkWtFunction(is_constructor, func, Wt):
287298
# OK, all checks've passed.
288299
return True
289300

301+
# =============================================================================
302+
# Getter functions: getSignals, getMembers, getConstructors, getIncludes etc.
303+
290304
def isSignal(func):
291305
if len(func.arguments) != 0:
292306
return False
@@ -344,7 +358,7 @@ def getMembers(global_namespace, module_name, blacklisted):
344358
if module_name == 'WWidget' or module_name == 'WApplication':
345359
base_r = '0'
346360
if not base_r:
347-
raise Exception('Unable to bind %s, because it isnt descendant of WWidget' % module_name)
361+
raise Exception('Unable to bind %s, because it isn\'t descendant of WWidget' % module_name)
348362
custom_matcher = pygccxml.declarations.custom_matcher_t(
349363
lambda decl: checkWtFunction(False, decl, Wt),
350364
)
@@ -376,8 +390,8 @@ def noParent(args):
376390
# For widget tests generation.
377391
# Function returns flag - constructors type:
378392
# - 0 means error - no constructors supported by luawt.test are available;
379-
# - 1 - only no-args constructors are available
380-
# - 2 means that there're constructors with single WContainerWidget arg
393+
# - 1 - only no-args constructors are available;
394+
# - 2 means that there're constructors with single WContainerWidget arg.
381395
def getConstructorsType(constructors):
382396
has_void_args = False
383397
has_sing_arg = False
@@ -444,12 +458,16 @@ def getIncludes(module_name, methods, constructors):
444458
includes += getModulesFromFuncSig(method)
445459
for constructor in constructors:
446460
includes += getModulesFromFuncSig(constructor)
447-
# Erase repeats
461+
# Erase repeats.
448462
return set(includes)
449463

450464
def getModuleName(filename):
451465
return os.path.basename(filename)
452466

467+
468+
# =============================================================================
469+
# Generator functions (actual logic of generating the code of bindings).
470+
453471
INCLUDES_TEMPLATE = r'''
454472
#include "boost-xtime.hpp"
455473
@@ -569,7 +587,7 @@ def getBuiltinTypeArgument(options):
569587
return code
570588
else:
571589
if 'static_cast' in options['func']:
572-
# Enum
590+
# Enum.
573591
return get_enum_arg_template.lstrip() % options
574592
else:
575593
return get_builtin_arg_template.lstrip() % options
@@ -656,12 +674,12 @@ def returnValue(return_type):
656674
else:
657675
ref_str = ''
658676
builtin_type = getBuiltinType(return_type)
659-
# func - function for returning values to Lua
677+
# func - function for returning values to Lua.
660678
if builtin_type:
661679
_, func_name = BUILTIN_TYPES_CONVERTERS[builtin_type]
662680
else:
663681
func_name = 'luawt_toLua'
664-
# Is reference
682+
# Is reference.
665683
if '&' in return_type:
666684
ref_str = '&'
667685
# Method to convert problematic type to built-in.
@@ -857,7 +875,7 @@ def generateModuleFunc(module_name, base, is_not_abstract):
857875
assert(base);
858876
'''
859877
if base == '0':
860-
# WApplication or WWidget
878+
# WApplication or WWidget.
861879
get_base = ''
862880
else:
863881
get_base = base_frame.strip() % base.name
@@ -1017,6 +1035,10 @@ def generateModule(module_name, methods, base, constructors, signals):
10171035
))
10181036
return ''.join(source)
10191037

1038+
# =============================================================================
1039+
# Main functionality functions (called directly from main()).
1040+
# bind, generateBlacklist, addModuleToLists, collectMembers.
1041+
10201042
def getMatchRange(pattern, content):
10211043
first, last = 0, 0
10221044
for i, line in enumerate(content):
@@ -1066,17 +1088,6 @@ def addItem(
10661088
content.insert(curr_index, added_str)
10671089
return ''.join(content)
10681090

1069-
def writeToFile(filename, what):
1070-
with open(filename, 'wt') as f:
1071-
f.write(what)
1072-
1073-
def readFile(filename):
1074-
with open(filename, 'rt') as f:
1075-
return f.readlines()
1076-
1077-
def writeSourceToFile(module_name, source):
1078-
writeToFile('src/luawt/%s' % module_name, source)
1079-
10801091
def addItemToFiles(parameters, module_name, Wt = None):
10811092
for parameter in parameters:
10821093
content = readFile(parameter['filename'])
@@ -1179,7 +1190,7 @@ def bind(modules, module_only, blacklist, gen_enums=False):
11791190
if not module_only:
11801191
addModuleToLists(module_name, global_namespace.namespace('Wt'))
11811192
if constructors:
1182-
# Is not abstract
1193+
# Is not abstract.
11831194
addTest(module_name, constructors_type)
11841195
writeSourceToFile(module_name + '.cpp', source)
11851196
except Exception as e:
@@ -1276,6 +1287,22 @@ def generateBlacklist(mem1, mem2):
12761287
blacklisted['signatures'].sort()
12771288
return blacklist
12781289

1290+
# =============================================================================
1291+
# Utility functions.
1292+
1293+
def writeToFile(filename, what):
1294+
with open(filename, 'wt') as f:
1295+
f.write(what)
1296+
1297+
def readFile(filename):
1298+
with open(filename, 'rt') as f:
1299+
return f.readlines()
1300+
1301+
def writeSourceToFile(module_name, source):
1302+
writeToFile('src/luawt/%s' % module_name, source)
1303+
1304+
# =============================================================================
1305+
12791306
def main():
12801307
parser = argparse.ArgumentParser(
12811308
description=__doc__,

0 commit comments

Comments
 (0)