Better support for typedefs

This commit is contained in:
Gustavo J. A. M. Carneiro
2009-04-29 18:47:36 +01:00
parent 61975aa5ff
commit 4afd533b9f
7 changed files with 47 additions and 15 deletions
+8 -12
View File
@@ -657,7 +657,7 @@ class ModuleParser(object):
self.module.add_include(inc)
for pygen_sink in self._get_all_pygen_sinks():
pygen_sink.writeln("from pybindgen import Module, FileCodeSink, param, retval, cppclass")
pygen_sink.writeln("from pybindgen import Module, FileCodeSink, param, retval, cppclass, typehandlers")
pygen_sink.writeln()
pygen_sink = self._get_main_pygen_sink()
@@ -1172,17 +1172,13 @@ pybindgen.settings.error_handler = ErrorHandler()
for alias in module_namespace.typedefs(function=self.location_filter,
recursive=False, allow_empty=True):
## handle "typedef int Something;"
if isinstance(alias.type, cpptypes.int_t):
param_cls, dummy_transf, dummy_traits = typehandlers.base.param_type_matcher.lookup('int')
for ctype in param_cls.CTYPES:
#print >> sys.stderr, "%s -> int" % ctype.replace('int', alias.name)
typehandlers.base.param_type_matcher.register(ctype.replace('int', alias.name), param_cls)
return_cls, dummy_transf, dummy_traits = typehandlers.base.return_type_matcher.lookup('int')
for ctype in return_cls.CTYPES:
#print >> sys.stderr, "%s -> int" % ctype.replace('int', alias.name)
typehandlers.base.return_type_matcher.register(ctype.replace('int', alias.name), return_cls)
continue
type_from_name = normalize_name(str(alias.type))
type_to_name = normalize_name(utils.ascii('::'.join([module.cpp_namespace_prefix, alias.name])))
typehandlers.base.add_type_alias(type_from_name, type_to_name)
pygen_sink = self._get_pygen_sink_for_definition(alias)
if pygen_sink:
pygen_sink.writeln("typehandlers.add_type_alias(%r, %r)" % (type_from_name, type_to_name))
## Look for forward declarations of class/structs like
## "typedef struct _Foo Foo"; these are represented in
+2
View File
@@ -10,3 +10,5 @@ import floattype
import pyobjecttype
from base import add_type_alias
+17 -3
View File
@@ -1301,6 +1301,7 @@ class TypeMatcher(object):
"""Constructor"""
self._types = {}
self._transformations = []
self._type_aliases = {}
def register_transformation(self, transformation):
@@ -1317,7 +1318,14 @@ class TypeMatcher(object):
if name in self._types:
raise ValueError("return type %s already registered" % (name,))
self._types[name] = type_handler
def _raw_lookup_with_alias_support(self, name):
try:
alias = self._type_aliases[name]
except KeyError:
return self._types[name]
else:
return self._raw_lookup_with_alias_support(alias)
def lookup(self, name):
"""
@@ -1333,7 +1341,7 @@ class TypeMatcher(object):
noconst_name = str(given_type_traits.ctype_no_modifiers)
tried_names = [noconst_name]
try:
rv = self._types[noconst_name], None, given_type_traits
rv = self._raw_lookup_with_alias_support(noconst_name), None, given_type_traits
except KeyError:
logger.debug("try to lookup type handler for %r => failure", name)
## Now try all the type transformations
@@ -1344,7 +1352,7 @@ class TypeMatcher(object):
untransformed_type_traits = ctypeparser.TypeTraits(untransformed_name)
untransformed_name = str(untransformed_type_traits.ctype_no_modifiers)
try:
rv = self._types[untransformed_name], transf, untransformed_type_traits
rv = self._raw_lookup_with_alias_support(untransformed_name), transf, untransformed_type_traits
except KeyError:
logger.debug("try to lookup type handler for %r => failure (%r)", untransformed_name)
tried_names.append(untransformed_name)
@@ -1362,7 +1370,13 @@ class TypeMatcher(object):
"Returns an iterator over all registered items"
return self._types.iteritems()
def add_type_alias(self, from_type_name, to_type_name):
self._type_aliases[to_type_name] = from_type_name
return_type_matcher = TypeMatcher()
param_type_matcher = TypeMatcher()
def add_type_alias(from_type_name, to_type_name):
return_type_matcher.add_type_alias(from_type_name, to_type_name)
param_type_matcher.add_type_alias(from_type_name, to_type_name)
+9
View File
@@ -418,3 +418,12 @@ get_set ()
return rv;
}
namespace xpto
{
FlowId
get_flow_id (FlowId flowId)
{
return flowId + 1;
}
}
+5
View File
@@ -459,6 +459,9 @@ void delete_some_object();
namespace xpto
{
typedef uint32_t FlowId;
FlowId get_flow_id (FlowId flowId);
std::string some_function();
class SomeClass
@@ -868,4 +871,6 @@ inline Tupl operator - (Tupl const &a, Tupl const &b)
#endif /* !FOO_H_ */
+3
View File
@@ -270,6 +270,9 @@ int %s::custom_method_added_by_a_hook(int x)
xpto.add_typedef(Foo, 'FooXpto')
xpto.add_function('get_foo_datum', 'std::string', [Parameter.new('const xpto::FooXpto&', 'foo')])
typehandlers.add_type_alias('uint32_t', 'xpto::FlowId')
xpto.add_function('get_flow_id', 'xpto::FlowId', [Parameter.new('xpto::FlowId', 'flowId')])
## ---- some implicity conversion APIs
+3
View File
@@ -1066,6 +1066,9 @@ class TestFoo(unittest.TestCase):
self.assertEqual(r.x, t1.x / t2.x)
self.assertEqual(r.y, t1.y / t2.y)
def test_int_typedef(self):
rv = foo.xpto.get_flow_id(123)
self.assertEqual(rv, 124)
if __name__ == '__main__':
unittest.main()