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
284 msg = [ super( variable_matcher_t, self ).__str__() ]
285 if msg == [ 'any' ]:
286 msg = []
287 if not None is self.type:
288 msg.append( '(value type==%s)' % str(self.type) )
289 if not msg:
290 msg.append( 'any' )
291 return ' and '.join( msg )
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
422 msg = [ super( operator_matcher_t, self ).__str__() ]
423 if msg == [ 'any' ]:
424 msg = []
425 if not None is self.symbol:
426 msg.append( '(symbol==%s)' % str(self.symbol) )
427 if not msg:
428 msg.append( 'any' )
429 return ' and '.join( msg )
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
456 text = self.function( decl )
457 return bool( self.regex.match( text ) )
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
524 return bool( self.function( decl ) )
525
527 return '(user criteria)'
528