aboutsummaryrefslogtreecommitdiff
path: root/tools/bindings_generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bindings_generator.py')
-rwxr-xr-xtools/bindings_generator.py109
1 files changed, 70 insertions, 39 deletions
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py
index e1c1ab4b..17df1231 100755
--- a/tools/bindings_generator.py
+++ b/tools/bindings_generator.py
@@ -95,24 +95,38 @@ all_h.write(text)
all_h.close()
parsed = CppHeaderParser.CppHeader(all_h_name)
-for classname, clazz in parsed.classes.iteritems():
- print 'zz see', classname
+print 'zz dir: ', parsed.__dict__.keys()
+for classname, clazz in parsed.classes.items() + parsed.structs.items():
+ print 'zz see', classname, clazz, type(clazz)
classes[classname] = clazz
- clazz['methods'] = clazz['methods']['public'] # CppHeaderParser doesn't have 'public' etc. in structs. so equalize to that
+ if type(clazz['methods']) == dict:
+ clazz['saved_methods'] = clazz['methods']
+ clazz['methods'] = clazz['methods']['public'] # CppHeaderParser doesn't have 'public' etc. in structs. so equalize to that
if '::' in classname:
assert classname.count('::') == 1
parents[classname.split('::')[1]] = classname.split('::')[0]
- for sname, struct in clazz._public_structs.iteritems():
- parents[sname] = classname
- classes[classname + '::' + sname] = struct
- struct['name'] = sname # Missing in CppHeaderParser
- print 'zz seen struct %s in %s' % (sname, classname)
-
+ if hasattr(clazz, '_public_structs'): # This is a class
+ for sname, struct in clazz._public_structs.iteritems():
+ parents[sname] = classname
+ classes[classname + '::' + sname] = struct
+ struct['name'] = sname # Missing in CppHeaderParser
+ print 'zz seen struct %s in %s' % (sname, classname)
+
+ if 'fields' in clazz: # This is a struct
+ print 'zz add properties!'
+ clazz['properties'] = { 'public': clazz['fields'] }
+ clazz['name'] = classname
+ clazz['inherits'] = []
print 'zz parents: ', parents
-for classname, clazz in classes.iteritems():
+def check_has_constructor(clazz):
+ for method in clazz['methods']:
+ if method['constructor'] and not method['destructor']: return True
+ return False
+
+for classname, clazz in parsed.classes.items() + parsed.structs.items():
# Various precalculations
print 'zz precalc', classname
for method in clazz['methods'][:]:
@@ -157,7 +171,7 @@ for classname, clazz in classes.iteritems():
print 'zz subsubsub ', classname, method['name'], method['parameters'][0]
method['name'] = 'op_sub'
if len(method['parameters'][0]) == 0:
- method['operator'] = ' return -*self; // %d' % len(method['parameters'][0])
+ method['operator'] = ' static %s ret; ret = -*self; return ret;' % method['returns']
else:
method['operator'] = ' return *self -= arg0; // %d : %s' % (len(method['parameters'][0]), method['parameters'][0][0]['name'])
elif 'imul' in method['name']:
@@ -237,21 +251,31 @@ for classname, clazz in classes.iteritems():
}]],
})
- # Add destroyer
- if not clazz.get('abstract'):
- clazz['methods'].append({
- 'destroyer': True,
- 'name': '__destroy__',
- 'constructor': False,
- 'destructor': False,
- 'static': False,
- 'returns': 'void',
- 'returns_text': 'void',
- 'returns_reference': False,
- 'returns_pointer': False,
- 'pure_virtual': False,
- 'parameters': [[]],
- })
+ print 'zz is effectively abstract?', clazz['name'], classname, '0'
+ if 'saved_methods' in clazz and not check_has_constructor(clazz):
+ print 'zz is effectively abstract?', clazz['name'], '1'
+ # Having a private constructor and no public constructor means you are, in effect, abstract
+ for private_method in clazz['saved_methods']['private']:
+ print 'zz is effectively abstract?', clazz['name'], '2'
+ if private_method['constructor']:
+ print 'zz is effectively abstract?', clazz['name'], '3'
+ clazz['effectively_abstract'] = True
+
+ # Add destroyer
+ if not clazz.get('abstract') and not clazz.get('effectively_abstract'):
+ clazz['methods'].append({
+ 'destroyer': True,
+ 'name': '__destroy__',
+ 'constructor': False,
+ 'destructor': False,
+ 'static': False,
+ 'returns': 'void',
+ 'returns_text': 'void',
+ 'returns_reference': False,
+ 'returns_pointer': False,
+ 'pure_virtual': False,
+ 'parameters': [[]],
+ })
clazz['methods'] = filter(lambda method: not method.get('ignore'), clazz['methods'])
@@ -277,7 +301,7 @@ def copy_args(args):
ret.append(copiedarg)
return ret
-for classname, clazz in parsed.classes.iteritems():
+for classname, clazz in parsed.classes.items() + parsed.structs.items():
clazz['final_methods'] = {}
def explore(subclass, template_name=None, template_value=None):
@@ -286,10 +310,16 @@ for classname, clazz in parsed.classes.iteritems():
print classname, 'exploring', subclass['name'], '::', method['name']
if method['constructor']:
- if clazz != subclass: continue # Subclasses cannot directly use their parent's constructors
- if method['destructor']: continue # Nothing to do there
+ if clazz != subclass:
+ print "zz Subclasses cannot directly use their parent's constructors"
+ continue
+ if method['destructor']:
+ print 'zz Nothing to do there'
+ continue
- if method.get('operator') and subclass is not clazz: continue # Do not use parent class operators. Cast to that class if you need those operators (castObject)
+ if method.get('operator') and subclass is not clazz:
+ print 'zz Do not use parent class operators. Cast to that class if you need those operators (castObject)'
+ continue
if method['name'] not in clazz['final_methods']:
copied = clazz['final_methods'][method['name']] = {}
@@ -485,6 +515,7 @@ def generate_wrapping_code(classname):
# %(classname)s.prototype['fields'] = Runtime.generateStructInfo(null, '%(classname)s'); - consider adding this
def generate_class(generating_classname, classname, clazz): # TODO: deprecate generating?
+ print 'zz generating:', generating_classname, classname
generating_classname_head = generating_classname.split('::')[-1]
classname_head = classname.split('::')[-1]
@@ -498,6 +529,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge
gen_js.write('''Module['%s'] = %s;
''' % (generating_classname_head, generating_classname_head))
+ print 'zz methods: ', clazz['final_methods'].keys()
for method in clazz['final_methods'].itervalues():
mname = method['name']
if classname_head + '::' + mname in ignored:
@@ -509,7 +541,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge
destructor = method['destructor']
static = method['static']
- #print 'zz generating %s::%s. gets %s and returns %s' % (generating_classname, method['name'], str([arg['type'] for arg in method['parameters']]), method['returns_text'])
+ print 'zz generating %s::%s' % (generating_classname, method['name'])
if destructor: continue
if constructor and inherited: continue
@@ -644,7 +676,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge
print 'zz making return', classname, method['name'], method['returns'], return_value
if method['returns'] in classes:
# Generate a wrapper
- calls += 'return wrapPointer(%s, %s);' % (return_value, method['returns'].split('::')[-1])
+ calls += 'return wrapPointer(%s, Module.%s);' % (return_value, method['returns'].split('::')[-1])
else:
# Normal return
calls += ('return ' if ret != 'void' else '') + return_value + ';'
@@ -686,7 +718,7 @@ Module['%s'] = %s;
# Main loop
-for classname, clazz in classes.iteritems():
+for classname, clazz in parsed.classes.items() + parsed.structs.items():
if any([name in ignored for name in classname.split('::')]):
print 'zz ignoring', classname
continue
@@ -727,18 +759,17 @@ for classname, clazz in classes.iteritems():
print 'zz ignoring pure virtual class', classname, 'due to', method['name']
return True
- clazz['abstract'] = check_pure_virtual(clazz, [])
+ clazz['abstract'] = check_pure_virtual(clazz, []) or clazz.get('effectively_abstract')
+
print 'zz', classname, 'is abstract?', clazz['abstract']
#if check_pure_virtual(clazz, []):
# continue
# Add a constructor if none exist
- has_constructor = False
- for method in clazz['methods']:
- has_constructor = has_constructor or (method['constructor'] and not method['destructor'])
-
+ has_constructor = check_has_constructor(clazz)
+
print 'zz', classname, 'has constructor?', has_constructor
-
+
if not has_constructor:
if not clazz['abstract']:
print 'zz no constructor for', classname, 'and not abstract, so ignoring'