[pygccxml-commit] SF.net SVN: pygccxml:[1425] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-10-05 20:26:49
|
Revision: 1425 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1425&view=rev Author: roman_yakovenko Date: 2008-10-05 20:26:38 +0000 (Sun, 05 Oct 2008) Log Message: ----------- adding new warning Modified Paths: -------------- pyplusplus_dev/pyplusplus/messages/warnings_.py pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py pyplusplus_dev/unittests/duplicate_aliases_tester.py Modified: pyplusplus_dev/pyplusplus/messages/warnings_.py =================================================================== --- pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-10-05 20:21:17 UTC (rev 1424) +++ pyplusplus_dev/pyplusplus/messages/warnings_.py 2008-10-05 20:26:38 UTC (rev 1425) @@ -32,6 +32,10 @@ class execution_error( message_type ): prefix = 'execution error' +class code_generation_error( message_type ): + prefix = 'code generation error' + + W0000 = warning( '%s' ) #general message, usefull in few cases W1000 = compilation_error( @@ -246,6 +250,16 @@ W1064 = compilation_error( 'Py++ can not expose "%s" as "fake constructor" of "%s".' ' Only the following function types supported: %s' ) +W1065 = code_generation_error( + 'There are two or more classes that use same class wrapper alias("%s"). ' + 'Duplicated class wrapper aliases causes few problems, but the main one is that during ' + 'files generation Py++ uses class wrapper aliases for the file names. ' + 'Py++ will rewrite the file content and at best will introduce compile time error. ' + 'The worst case scenario: you will discover the problem during run-time.' + 'Use `wrapper_alias` property to change class wrapper alias value' + 'Other classes : %s' ) + + warnings = globals() all_warning_msgs = [] Modified: pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-10-05 20:21:17 UTC (rev 1424) +++ pyplusplus_dev/pyplusplus/module_creator/dependencies_manager.py 2008-10-05 20:26:38 UTC (rev 1425) @@ -11,7 +11,46 @@ from pygccxml import declarations from pyplusplus import decl_wrappers +class duplicated_names_reporter_t(object): + def __init__( self, decls, value_getter, msg ): + self.decls = decls + self.get_value = value_getter + self.msg = msg + def __select( self ): + duplicated = {} + for decl in self.decls: + value = self.get_value( decl ) + if not duplicated.has_key( value ): + duplicated[ value ] = set() + duplicated[ value ].add( decl ) + result = duplicated.copy() + for value, buggy_decls in duplicated.items(): + if 1 == len( buggy_decls ): + del result[ value ] + return result + + def __report_single( self, control_decl, duplicated, logger ): + value = self.get_value( control_decl ) + if value not in duplicated: + return + buggy_decls = duplicated[value].copy() + buggy_decls.remove( control_decl ) + warning = self.msg % ( value, os.linesep.join( map( str, buggy_decls ) ) ) + logger.warn( "%s;%s" % ( str( control_decl ), warning ) ) + + def report( self, logger ): + duplicated = self.__select() + for decl in self.decls: + self.__report_single( decl, duplicated, logger ) + +duplicated_aliases_reporter \ + = lambda decls: duplicated_names_reporter_t( decls, lambda d: d.alias, messages.W1047 ) + +duplicated_wrapper_aliases_reporter \ + = lambda decls: duplicated_names_reporter_t( decls, lambda d: d.wrapper_alias, messages.W1065 ) + + class manager_t( object ): def __init__( self, logger ): object.__init__( self ) @@ -21,41 +60,6 @@ def add_exported( self, decl ): self.__exported_decls.append( decl ) - def __select_duplicate_aliases( self, decls ): - duplicated = {} - for decl in decls: - if not duplicated.has_key( decl.alias ): - duplicated[ decl.alias ] = set() - duplicated[ decl.alias ].add( decl ) - for alias, buggy_decls in duplicated.items(): - if 1 == len( buggy_decls ): - del duplicated[ alias ] - return duplicated - - def __report_duplicate_aliases_impl( self, control_decl, duplicated ): - if control_decl.alias in duplicated: - buggy_decls = duplicated[control_decl.alias].copy() - buggy_decls.remove( control_decl ) - warning = messages.W1047 % ( control_decl.alias - , os.linesep.join( map( str, buggy_decls ) ) ) - self.__logger.warn( "%s;%s" % ( control_decl, warning ) ) - - if isinstance( control_decl, declarations.class_t ): - query = lambda i_decl: isinstance( i_decl, declarations.class_types ) \ - and i_decl.ignore == False - i_decls = control_decl.classes( query, recursive=False, allow_empty=True ) - i_duplicated = self.__select_duplicate_aliases( i_decls ) - for i_decl in i_decls: - self.__report_duplicate_aliases_impl( i_decl, i_duplicated ) - - def __report_duplicate_aliases( self ): - decls = filter( lambda decl: isinstance( decl, declarations.class_types ) \ - and isinstance( decl.parent, declarations.namespace_t ) - , self.__exported_decls ) - duplicated = self.__select_duplicate_aliases( decls ) - for decl in decls: - self.__report_duplicate_aliases_impl( decl, duplicated ) - def __is_std_decl( self, decl ): #Every class under std should be exported by Boost.Python and\\or Py++ #Also this is not the case right now, I prefer to hide the warnings @@ -76,46 +80,46 @@ if decl.already_exposed: return [] dependencies = decl.i_depend_on_them(recursive=False) - + if isinstance( decl, declarations.class_t ): dependencies = filter( lambda d: d.access_type != declarations.ACCESS_TYPES.PRIVATE - , dependencies ) - + , dependencies ) + return dependencies - def __has_unexposed_dependency( self, exported_ids, depend_on_decl, dependency ): + def __has_unexposed_dependency( self, exported_ids, depend_on_decl, dependency ): sptr_traits = declarations.smart_pointer_traits - + if None is depend_on_decl: return - + if self.__is_std_decl( depend_on_decl ): - return - + return + if sptr_traits.is_smart_pointer( depend_on_decl ): try: value_type = sptr_traits.value_type( depend_on_decl ) return self.__has_unexposed_dependency( exported_ids, value_type, dependency ) except RuntimeError: - pass - + pass + if isinstance( depend_on_decl, decl_wrappers.decl_wrapper_t ): if depend_on_decl.already_exposed: - return + return if isinstance( depend_on_decl, declarations.class_types ): if depend_on_decl.opaque: - return + return if dependency.hint == "base class": return #base class for some class don't have to be exported if isinstance( depend_on_decl, declarations.variable_t ): if not decl.expose_value: - return - + return + if isinstance( dependency.decl, declarations.variable_t ): #the only dependency of the variable is its type if not dependency.decl.expose_value: - return - + return + if dependency.hint == "return type": #in this case we don't check, the return type but the function if isinstance( dependency.decl, declarations.calldef_t ): @@ -124,13 +128,13 @@ return return id( depend_on_decl ) not in exported_ids - + def __find_out_used_but_not_exported( self ): used_not_exported = [] exported_ids = set( map( lambda d: id( d ), self.__exported_decls ) ) for decl in self.__exported_decls: - for dependency in self.__build_dependencies( decl ): - depend_on_decl = dependency.find_out_depend_on_declaration() + for dependency in self.__build_dependencies( decl ): + depend_on_decl = dependency.find_out_depend_on_declaration() if self.__has_unexposed_dependency( exported_ids, depend_on_decl, dependency ): if messages.filter_disabled_msgs([messages.W1040], depend_on_decl.disabled_messages ): #need to report dependency errors @@ -153,9 +157,43 @@ decls.append( os.linesep + ' ' + str( dependency.declaration ) ) return "%s;%s" % ( depend_on_decl, messages.W1040 % ''.join( decls ) ) + def __report_duplicated_aliases( self ): + decls = filter( lambda decl: isinstance( decl, declarations.class_types ) \ + and isinstance( decl.parent, declarations.namespace_t ) + , self.__exported_decls ) + + dar = duplicated_aliases_reporter( decls ) + dar.report( self.__logger ) + + classes = filter( lambda c: isinstance( c, declarations.class_t ), decls ) + query = lambda decl: isinstance( decl, declarations.class_types ) \ + and decl.ignore == False \ + and decl._already_exposed == False + + for cls in classes: + internal_decls = cls.decls( query, recursive=False, allow_empty=True) + dar = duplicated_aliases_reporter( internal_decls ) + dar.report( self.__logger ) + + def __report_duplicated_wrapper_aliases( self ): + decls = filter( lambda decl: isinstance( decl, declarations.class_t ) \ + and isinstance( decl.parent, declarations.namespace_t ) + , self.__exported_decls ) + + dwar = duplicated_wrapper_aliases_reporter( decls ) + dwar.report( self.__logger ) + + query = lambda decl: decl.ignore == False and decl._already_exposed == False + + for cls in decls: + internal_decls = cls.classes( query, recursive=False, allow_empty=True) + dwar = duplicated_wrapper_aliases_reporter( internal_decls ) + dwar.report( self.__logger ) + def inform_user( self ): used_not_exported_decls = self.__find_out_used_but_not_exported() groups = self.__group_by_unexposed( used_not_exported_decls ) for group in groups.itervalues(): self.__logger.warn( self.__create_dependencies_msg( group ) ) - self.__report_duplicate_aliases() + self.__report_duplicated_aliases() + self.__report_duplicated_wrapper_aliases() Modified: pyplusplus_dev/unittests/duplicate_aliases_tester.py =================================================================== --- pyplusplus_dev/unittests/duplicate_aliases_tester.py 2008-10-05 20:21:17 UTC (rev 1424) +++ pyplusplus_dev/unittests/duplicate_aliases_tester.py 2008-10-05 20:26:38 UTC (rev 1425) @@ -21,6 +21,7 @@ def customize(self, mb): classes = mb.classes( lambda decl: 'duplicate_aliases' in decl.name ) classes.alias = 'duplicate_aliases' + classes.wrapper_alias = 'wrapper_duplicate_aliases' def run_tests( self, module): #check compilation This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |