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