Package logilab-common-0 :: Package 36 :: Package 1 :: Module visitor
[frames] | no frames]

Source Code for Module logilab-common-0.36.1.visitor

 1  """A generic visitor abstract implementation. 
 2   
 3  :copyright: 2002-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
 4  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr 
 5  :license: General Public License version 2 - http://www.gnu.org/licenses 
 6  """ 
 7  __docformat__ = "restructuredtext en" 
 8   
9 -def no_filter(_):
10 return 1
11 12 # Iterators ###################################################################
13 -class FilteredIterator(object):
14
15 - def __init__(self, node, list_func, filter_func=None):
16 self._next = [(node, 0)] 17 if filter_func is None: 18 filter_func = no_filter 19 self._list = list_func(node, filter_func)
20
21 - def next(self):
22 try: 23 return self._list.pop(0) 24 except : 25 return None
26 27 # Base Visitor ################################################################
28 -class Visitor(object):
29
30 - def __init__(self, iterator_class, filter_func=None):
31 self._iter_class = iterator_class 32 self.filter = filter_func
33
34 - def visit(self, node, *args, **kargs):
35 """ 36 launch the visit on a given node 37 38 call 'open_visit' before the begining of the visit, with extra args 39 given 40 when all nodes have been visited, call the 'close_visit' method 41 """ 42 self.open_visit(node, *args, **kargs) 43 return self.close_visit(self._visit(node))
44
45 - def _visit(self, node):
46 iterator = self._get_iterator(node) 47 n = iterator.next() 48 while n: 49 result = n.accept(self) 50 n = iterator.next() 51 return result
52
53 - def _get_iterator(self, node):
54 return self._iter_class(node, self.filter)
55
56 - def open_visit(self, *args, **kargs):
57 """ 58 method called at the beginning of the visit 59 """ 60 pass
61
62 - def close_visit(self, result):
63 """ 64 method called at the end of the visit 65 """ 66 return result
67 68 # standard visited mixin ######################################################
69 -class VisitedMixIn(object):
70 """ 71 Visited interface allow node visitors to use the node 72 """
73 - def get_visit_name(self):
74 """ 75 return the visit name for the mixed class. When calling 'accept', the 76 method <'visit_' + name returned by this method> will be called on the 77 visitor 78 """ 79 try: 80 return self.TYPE.replace('-', '_') 81 except: 82 return self.__class__.__name__.lower()
83
84 - def accept(self, visitor, *args, **kwargs):
85 func = getattr(visitor, 'visit_%s' % self.get_visit_name()) 86 return func(self, *args, **kwargs)
87
88 - def leave(self, visitor, *args, **kwargs):
89 func = getattr(visitor, 'leave_%s' % self.get_visit_name()) 90 return func(self, *args, **kwargs)
91