Revision: 161
Author: roman_yakovenko
Date: 2006-05-24 13:19:26 -0700 (Wed, 24 May 2006)
ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=161&view=rev
Log Message:
-----------
commiting full implementation ( no unittests )
for member variable references
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/code_creators/class_declaration.py
pyplusplus_dev/pyplusplus/code_creators/member_variable.py
pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py
pyplusplus_dev/pyplusplus/module_builder/builder.py
pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py
pyplusplus_dev/pyplusplus/module_creator/creator.py
Modified: pyplusplus_dev/pyplusplus/code_creators/class_declaration.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/code_creators/class_declaration.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -13,6 +13,7 @@
import declaration_based
import array_1_registrator
import indexing_suites
+import member_variable
from pygccxml import declarations
class class_t( scoped.scoped_t ):
@@ -189,6 +190,9 @@
if isinstance( inst, indexing_suites.indexing_suite_t ):
return True
+ if isinstance( inst, member_variable.mem_var_ref_t ):
+ return True
+
return False
def _get_class_var_name(self):
Modified: pyplusplus_dev/pyplusplus/code_creators/member_variable.py
===================================================================
--- pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/code_creators/member_variable.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -416,10 +416,6 @@
return os.linesep.join( answer )
-
-
-
-
class mem_var_ref_t( member_variable_base_t ):
"""
Creates C++ code that creates accessor for class member variable, that has type reference.
@@ -429,34 +425,48 @@
, variable=variable
, wrapper=wrapper
, parent=parent)
+ self.param_sep = os.linesep + self.indent( self.PARAM_SEPARATOR, 2 )
- def _create_impl( self ):
- if self.declaration.type_qualifiers.has_static:
- add_property = 'add_static_property'
+ def _create_getter( self ):
+ answer = ['def']
+ answer.append( '( ' )
+ answer.append( '"get_%s"' % self.alias)
+ answer.append( self.param_sep )
+ answer.append( '(%s)(&%s)'
+ % ( self.wrapper.getter_type.decl_string, self.wrapper.getter_full_name ) )
+ if self.declaration.getter_call_policies:
+ answer.append( self.param_sep )
+ answer.append( self.declaration.getter_call_policies.create( self ) )
else:
- add_property = 'add_property'
- answer = [ add_property ]
+ answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) )
+ answer.append( ' )' )
+ return ''.join( answer )
+
+ def _create_setter( self ):
+ answer = ['def']
answer.append( '( ' )
- answer.append('"%s"' % self.alias)
- answer.append( self.PARAM_SEPARATOR )
+ answer.append( '"set_%s"' % self.alias)
+ answer.append( self.param_sep )
answer.append( '(%s)(&%s)'
- % ( self.wrapper.getter_type.decl_string, self.wrapper.getter_full_name ) )
-
+ % ( self.wrapper.setter_type.decl_string, self.wrapper.setter_full_name ) )
+ if self.declaration.setter_call_policies:
+ answer.append( self.param_sep )
+ answer.append( self.declaration.setter_call_policies.create( self ) )
+ else:
+ answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) )
+ answer.append( ' )' )
+ return ''.join( answer )
+
+ def _create_impl( self ):
+ #TODO: fix me, should not force class scope usage
+ answer = []
+ class_var_name = self.parent.class_var_name
+ answer.append( "%s.%s;" % (class_var_name, self._create_getter() ) )
if self.wrapper.has_setter:
- answer.append( self.PARAM_SEPARATOR )
- answer.append( '(%s)(&%s)'
- % ( self.wrapper.setter_type.decl_string, self.wrapper.setter_full_name ) )
- answer.append( ' ) ' )
-
- code = ''.join( answer )
- if len( code ) <= self.LINE_LENGTH:
- return code
- else:
- for i in range( len( answer ) ):
- if answer[i] == self.PARAM_SEPARATOR:
- answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) )
- return ''.join( answer )
-
+ answer.append( os.linesep )
+ answer.append( "%s.%s;" % (class_var_name, self._create_setter() ) )
+ return ''.join( answer )
+
class mem_var_ref_wrapper_t( declaration_based.declaration_based_t ):
"""
Creates C++ code that creates accessor for class member variable, that has type reference.
@@ -514,14 +524,28 @@
setter_type = property( _get_setter_type )
def _get_has_setter( self ):
- if declarations.is_fundamental( self._get_exported_var_type() ):
+ if declarations.is_const( declarations.remove_reference( self.declaration.type ) ):
+ return False
+ elif declarations.is_fundamental( self._get_exported_var_type() ):
return True
elif declarations.is_enum( self._get_exported_var_type() ):
return True
- elif declarations.is_const( declarations.remove_reference( self.declaration.type ) ):
- return False
else:
- return True
+ pass
+
+ no_ref = declarations.remove_reference( self.declaration.type )
+ no_const = declarations.remove_const( no_ref )
+ base_type = declarations.remove_alias( no_const )
+ if not isinstance( base_type, declarations.declarated_t ):
+ return True #TODO ????
+ decl = base_type.declaration
+ if decl.is_abstract:
+ return False
+ if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
+ return False
+ if not declarations.has_trivial_copy(decl):
+ return False
+ return True
has_setter = property( _get_has_setter )
def _create_impl(self):
Modified: pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py
===================================================================
--- pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/decl_wrappers/variable_wrapper.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -10,25 +10,33 @@
def __init__(self, *arguments, **keywords):
declarations.variable_t.__init__(self, *arguments, **keywords )
decl_wrapper.decl_wrapper_t.__init__( self )
- self._call_policies = None
-
- def _get_call_policies( self ):
- return self._call_policies
- def _set_call_policies( self, call_policies ):
- self._call_policies = call_policies
+ self._getter_call_policies = None
+ self._setter_call_policies = None
+
+ __call_policies_doc__ = \
+ """There are usecase, when exporting member variable forces pyplusplus to
+ create accessors functions. Sometime, those functions requires call policies.
+ To be more specific: when you export member variable that has reference or
+ pointer type, you need to tell boost.python library how to manage object
+ life-time. In all cases, pyplusplus will give reasonable default value. I am
+ sure, that there are use cases, when you need to change it. You should use this
+ property to change it.
+ """
- __call_policies_doc__ = \
- """There are usecase, when exporting member variable forces pyplusplus to
- create accessors functions. Sometime, those functions requires call policies.
- To be more specific: when you export member variable that has reference or
- pointer type, you need to tell boost.python library how to manage object
- life-time. In all cases, pyplusplus will give reasonable default value. I am
- sure, that there are use cases, when you need to change it. You should use this
- property to change it.
- """
- call_policies = property( _get_call_policies, _set_call_policies
- , doc=__call_policies_doc__ )
+ def get_getter_call_policies( self ):
+ return self._getter_call_policies
+ def set_getter_call_policies( self, call_policies ):
+ self._getter_call_policies = call_policies
+ getter_call_policies = property( get_getter_call_policies, set_getter_call_policies
+ , doc=__call_policies_doc__ )
+ def get_setter_call_policies( self ):
+ return self._setter_call_policies
+ def set_setter_call_policies( self, call_policies ):
+ self._setter_call_policies = call_policies
+ setter_call_policies = property( get_setter_call_policies, set_setter_call_policies
+ , doc=__call_policies_doc__ )
+
def _exportable_impl( self ):
if not isinstance( self.parent, declarations.class_t ):
return ''
Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -135,6 +135,13 @@
, flatten_decls )
map( lambda calldef: calldef.set_call_policies( call_policies_resolver( calldef ) )
, calldefs )
+ mem_vars = filter( lambda decl: isinstance( decl, decls_package.variable_t )
+ and isinstance( decl.parent, decls_package.class_t )
+ , flatten_decls )
+ map( lambda mem_var: mem_var.set_getter_call_policies( call_policies_resolver( mem_var, 'get' ) )
+ , mem_vars )
+ map( lambda mem_var: mem_var.set_setter_call_policies( call_policies_resolver( mem_var, 'set' ) )
+ , mem_vars )
def print_declarations(self, decl=None, detailed=True, recursive=True, writer=sys.stdout.write):
"""
Modified: pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/module_creator/call_policies_resolver.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -11,7 +11,7 @@
def __init__( self ):
object.__init__( self )
- def __call__(self, decl):
+ def __call__(self, decl, hint=None):
raise NotImplementedError()
class default_policy_resolver_t(resolver_t):
@@ -30,7 +30,7 @@
return decl_wrappers.default_call_policies()
return None
- def __call__(self, calldef):
+ def __call__(self, calldef, hint=None):
if not isinstance( calldef, declarations.calldef_t ):
return None
@@ -46,7 +46,7 @@
def __init__( self ):
resolver_t.__init__( self )
- def __call__( self, calldef ):
+ def __call__( self, calldef, hint=None ):
if not isinstance( calldef, declarations.calldef_t ):
return None
@@ -66,7 +66,7 @@
self.__const_wchar_pointer \
= declarations.pointer_t( declarations.const_t( declarations.wchar_t() ) )
- def __call__(self, calldef):
+ def __call__(self, calldef, hint=None):
if not isinstance( calldef, declarations.calldef_t ):
return None
@@ -87,7 +87,7 @@
def __init__( self ):
resolver_t.__init__( self )
- def __call__(self, calldef):
+ def __call__(self, calldef, hint=None):
if not isinstance( calldef, declarations.calldef_t ):
return None
@@ -112,23 +112,43 @@
def __init__( self ):
resolver_t.__init__( self )
- def __init__( self, variable ):
+ def __call__( self, variable, hint=None ):
if not isinstance( variable, declarations.variable_t ):
return None
+
+ assert hint in ( 'get', 'set' )
if not declarations.is_reference( variable.type ):
return None
- no_ref = declarations.remove_reference( self.declaration.type )
+ no_ref = declarations.remove_reference( variable.type )
base_type = declarations.remove_const( no_ref )
if declarations.is_fundamental( base_type ) or declarations.is_enum( base_type ):
#the relevant code creator will generate code, that will return this member variable
#by value
- return decl_wrappers.default_call_policies()
-
-
- return self.declaration.type
-
+ return decl_wrappers.default_call_policies()
+
+ if not isinstance( base_type, declarations.declarated_t ):
+ return None
+
+ base_type = declarations.remove_alias( base_type )
+ decl = base_type.declaration
+
+ if decl.is_abstract:
+ return None
+ if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
+ return None
+ if not declarations.has_trivial_copy(decl):
+ return None
+ if hint == 'get':
+ #if we rich this line, it means that we are able to create an obect using
+ #copy constructor.
+ if declarations.is_const( no_ref ):
+ return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference )
+ else:
+ return decl_wrappers.return_value_policy( decl_wrappers.copy_non_const_reference )
+ else:
+ return decl_wrappers.default_call_policies()
class built_in_resolver_t(resolver_t):
def __init__( self, config=None):
@@ -139,10 +159,11 @@
if not config or config.boost_python_supports_void_ptr:
self.__resolvers.append( void_pointer_resolver_t() )
self.__resolvers.append( return_internal_reference_resolver_t() )
+ self.__resolvers.append( variable_accessors_resolver_t() )
- def __call__( self, calldef ):
+ def __call__( self, calldef, hint=None ):
for resolver in self.__resolvers:
- resolved = resolver( calldef )
+ resolved = resolver( calldef, hint )
if resolved:
return resolved
return None
Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-05-24 12:36:11 UTC (rev 160)
+++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-05-24 20:19:26 UTC (rev 161)
@@ -664,6 +664,10 @@
wrapper = code_creators.member_variable_wrapper_t( variable=self.curr_decl )
maker = code_creators.member_variable_t( variable=self.curr_decl, wrapper=wrapper )
elif declarations.is_reference( self.curr_decl.type ):
+ if None is self.curr_decl.getter_call_policies:
+ self.curr_decl.getter_call_policies = self.__call_policies_resolver( self.curr_decl, 'get' )
+ if None is self.curr_decl.setter_call_policies:
+ self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' )
wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl )
maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper )
else:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|