1   
  2   
  3   
  4   
  5   
  6  """ 
  7  defines all "built-in" classes that implement declarations compare functionality 
  8  according to some criteria 
  9  """ 
 10   
 11  import os 
 12  import re 
 13  import types 
 14  import algorithm 
 15  import variable 
 16  import namespace 
 17  import calldef 
 18  import cpptypes 
 19  import templates 
 20  import class_declaration 
 21  from pygccxml import utils 
 22   
 24      """matcher_base_t class defines interface for classes that will implement 
 25         compare functionality according to some criteria. 
 26      """ 
 29   
 31          raise NotImplementedError( "matcher must always implement the __call__() method." ) 
  32   
 36   
 40   
 42          """or-operator (|)""" 
 43          return or_matcher_t([self, other]) 
  44   
 46          return "base class for all matchers" 
   47   
 49      """Combine several other matchers with "&". 
 50   
 51      For example: find all private functions with name XXX 
 52   
 53      C{ matcher = access_type_matcher_t( 'private' ) & calldef_matcher_t( name='XXX' ) } 
 54      """ 
 58   
 64   
 66          return " & ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) 
   67   
 68   
 70      """Combine several other matchers with "|". 
 71   
 72      For example: find all functions and variables with name 'XXX' 
 73   
 74      C{ matcher = variable_matcher_t( name='XXX' ) | calldef_matcher_t( name='XXX' ) } 
 75   
 76      """ 
 80   
 86   
 88          return " | ".join( map( lambda x: "(%s)" % str( x ), self.matchers ) ) 
   89   
 90   
 92      """Return the inverse result of matcher, using "~" 
 93   
 94      For example: find all private and protected declarations 
 95   
 96      C{ matcher = ~access_type_matcher_t( 'private' ) } 
 97   
 98      """ 
102   
105   
107          return "~(%s)"%str(self.matcher) 
  108   
110      """ 
111      Instance of this class will match declarations by next criteria: 
112            - declaration name, also could be fully qualified name 
113              Example: wstring or ::std::wstring 
114            - declaration type 
115              Example: L{class_t}, L{namespace_t}, L{enumeration_t} 
116            - location within file system ( file or directory ) 
117      """ 
118 -    def __init__( self, name=None, decl_type=None, header_dir=None, header_file=None ): 
 119          """ 
120          @param decl_type: declaration type to match by. For example L{enumeration_t}. 
121          @type decl_type: any class that derives from L{declarations.declaration_t} class 
122   
123          @param name: declaration name, could be full name. 
124          @type name: str 
125   
126          @param header_dir: absolute directory path 
127          @type header_dir: str 
128   
129          @param header_file: absolute file path 
130          @type header_file: str 
131   
132          """ 
133           
134           
135           
136           
137          matcher_base_t.__init__( self ) 
138          self.decl_type = decl_type 
139          self.__name = None 
140          self.__opt_is_tmpl_inst = None 
141          self.__opt_tmpl_name = None 
142          self.__opt_is_full_name = None 
143          self.__decl_name_only = None 
144   
145          self._set_name( name ) 
146   
147          self.header_dir = header_dir 
148          self.header_file = header_file 
149   
150          if self.header_dir: 
151              self.header_dir = utils.normalize_path( self.header_dir ) 
152              if not os.path.isabs( self.header_dir ): 
153                  raise RuntimeError( "Path to header directory should be absolute!" ) 
154   
155          if self.header_file: 
156              self.header_file = utils.normalize_path( self.header_file ) 
157              if not os.path.isabs( self.header_file ): 
158                  raise RuntimeError( "Path to header file should be absolute!" ) 
 159   
162   
164          self.__name = name 
165          if not self.__name: 
166              self.__opt_is_tmpl_inst = None 
167              self.__opt_tmpl_name = None 
168              self.__opt_is_full_name = None 
169              self.__decl_name_only = None 
170          else: 
171              self.__opt_is_tmpl_inst = templates.is_instantiation( self.__name ) 
172              self.__opt_tmpl_name = templates.name( self.__name ) 
173              if self.__opt_is_tmpl_inst: 
174                  if '::' in self.__opt_tmpl_name: 
175                      self.__opt_is_full_name = True 
176                      self.__decl_name_only = self.__opt_tmpl_name.split('::')[-1] 
177                  else: 
178                      self.__opt_is_full_name = False 
179                      self.__decl_name_only = self.__opt_tmpl_name 
180                  self.__name = templates.normalize( name )             
181              else: 
182                  if '::' in self.__name: 
183                      self.__opt_is_full_name = True 
184                      self.__decl_name_only = self.__name.split('::')[-1] 
185                  else: 
186                      self.__opt_is_full_name = False 
187                      self.__decl_name_only = self.__name 
 188   
189   
190      name = property( _get_name, _set_name ) 
191   
193          msg = [] 
194          if not None is self.decl_type: 
195              msg.append( '(decl type==%s)' % self.decl_type.__name__ ) 
196          if not None is self.name: 
197              msg.append( '(name==%s)' % self.name ) 
198          if not None is self.header_dir: 
199              msg.append( '(header dir==%s)' % self.header_dir ) 
200          if not None is self.header_file: 
201              msg.append( '(header file==%s)' % self.header_file ) 
202          if not msg: 
203              msg.append( 'any' ) 
204          return ' and '.join( msg ) 
 205   
224   
245   
247          return self.__opt_is_full_name 
 248   
250          return self.__decl_name_only 
 251      decl_name_only = property( _get_decl_name_only ) 
 252   
254      """ 
255      Instance of this class will match variables by next criteria: 
256          - L{declaration_matcher_t} criteria 
257          - variable type. Example: L{int_t} or 'int' 
258      """ 
259 -    def __init__( self, name=None, type=None, header_dir=None, header_file=None ): 
 270   
282   
 292   
293   
295      """Instance of this class will match namespaces by name.""" 
296   
299   
 307   
308   
310      """ 
311      Instance of this class will match callable by next criteria: 
312          - L{declaration_matcher_t} criteria 
313          - return type. Example: L{int_t} or 'int' 
314          - argument types 
315      """ 
316   
317 -    def __init__( self, name=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): 
 318          """ 
319          @param return_type: callable return type 
320          @type return_type: string or instance of L{type_t} derived class 
321   
322          @param arg_types: list of function argument types. arg_types can contain. 
323          Any item within the list could be string or instance of L{type_t} derived 
324          class. If you don't want some argument to participate in match you can 
325          put None. For example: 
326   
327          C{ calldef_matcher_t( arg_types=[ 'int &', None ] ) } 
328   
329          will match all functions that takes 2 arguments, where the first one is 
330          reference to integer and second any 
331          @type arg_types: list 
332          """ 
333          if None is decl_type: 
334              decl_type = calldef.calldef_t 
335          declaration_matcher_t.__init__( self 
336                                          , name=name 
337                                          , decl_type=decl_type 
338                                          , header_dir=header_dir 
339                                          , header_file=header_file ) 
340   
341          self.return_type = return_type 
342          self.arg_types = arg_types 
 343   
345          if not super( calldef_matcher_t, self ).__call__( decl ): 
346              return False 
347          if not None is self.return_type \ 
348             and not self.__compare_types( self.return_type, decl.return_type ): 
349              return False 
350          if self.arg_types: 
351              if isinstance( self.arg_types, (types.ListType, types.TupleType)): 
352                  if len(self.arg_types) != len( decl.arguments ): 
353                      return False 
354                  for type_or_str, arg in zip( self.arg_types, decl.arguments ): 
355                      if None == type_or_str: 
356                          continue 
357                      else: 
358                          if not self.__compare_types( type_or_str, arg.type ): 
359                              return False 
360          return True 
 361   
363          assert type_or_str 
364          if type is None: 
365              return False 
366          if isinstance( type_or_str, cpptypes.type_t ): 
367              if type_or_str != type: 
368                  return False 
369          else: 
370              if type_or_str != type.decl_string: 
371                  return False 
372          return True 
 373   
375          msg = [ super( calldef_matcher_t, self ).__str__() ] 
376          if msg == [ 'any' ]: 
377              msg = [] 
378          if not None is self.return_type: 
379              msg.append( '(return type==%s)' % str(self.return_type) ) 
380          if self.arg_types: 
381              for i in range( len( self.arg_types ) ): 
382                  if self.arg_types[i] is None: 
383                      msg.append( '(arg %d type==any)' % i ) 
384                  else: 
385                      msg.append( '(arg %d type==%s)' % ( i, str( self.arg_types[i] ) ) ) 
386          if not msg: 
387              msg.append( 'any' ) 
388          return ' and '.join( msg ) 
  389   
390   
392      """ 
393      Instance of this class will match operators by next criteria: 
394          - L{calldef_matcher_t} criteria 
395          - operator symbol: =, !=, (), [] and etc 
396      """ 
397 -    def __init__( self, name=None, symbol=None, return_type=None, arg_types=None, decl_type=None, header_dir=None, header_file=None): 
 412   
420   
 430   
432      """ 
433      Instance of this class will match declaration using regular expression. 
434      User should supply a function that will extract from declaration desired 
435      information as string. Later, this matcher will match that string using 
436      user regular expression. 
437      """ 
438 -    def __init__( self, regex, function=None ): 
 439          """ 
440          @param regex: regular expression 
441          @type regex: string, an instance of this class will compile it for you 
442   
443          @param function: function that will be called to get an information from 
444          declaration as string. As input this function takes 1 argument: reference 
445          to declaration. Return value should be string. If function is None, then 
446          the matcher will use declaration name. 
447   
448          """ 
449          matcher_base_t.__init__(self) 
450          self.regex = re.compile( regex ) 
451          self.function = function 
452          if None is self.function: 
453              self.function = lambda decl: decl.name 
 454   
458   
460          return '(regex=%s)' % self.regex 
  461   
463      """ 
464      Instance of this class will match declaration by its access type: public, 
465      private or protected. If declarations does not have access type, for example 
466      free function, then False will be returned. 
467      """ 
468   
470          """ 
471          @param access_type: declaration access type 
472          @type access_type: L{ACCESS_TYPES} defines few consts for your convinience. 
473          Any way you can pass public, private or protected as argument to this function 
474          """ 
475          matcher_base_t.__init__( self ) 
476          self.access_type = access_type 
 477   
482   
 485   
487      """ 
488      Instance of this class will match declaration by its virtuality type: not virtual, 
489      virtual or pure virtual. If declarations does not have virtuality type, for example 
490      free function, then False will be returned. 
491      """ 
492   
494          """ 
495          @param access_type: declaration access type 
496          @type access_type: L{VIRTUALITY_TYPES} defines few consts for your convinience. 
497          """ 
498          matcher_base_t.__init__( self ) 
499          self.virtuality_type = virtuality_type 
 500   
505   
507          return '(virtuality type=%s)' % self.virtuality_type 
  508   
509   
511      """ 
512      Instance of this class will match declaration by user custom criteria. 
513      """ 
514   
516          """ 
517          @param function: callable, that takes single argument - declaration instance 
518                           should return True or False 
519          """ 
520          matcher_base_t.__init__( self ) 
521          self.function = function 
 522   
525   
527          return '(user criteria)' 
  528