root / logilab.pylintinstaller / logilab / common / visitor.py

Revision 202:d67e86292521, 3.3 kB (checked in by tziade@…, 9 months ago)

added logilab.pylintinstaller

Line 
1# This program is free software; you can redistribute it and/or modify it under
2# the terms of the GNU General Public License as published by the Free Software
3# Foundation; either version 2 of the License, or (at your option) any later
4# version.
5#
6# This program is distributed in the hope that it will be useful, but WITHOUT
7# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9#
10# You should have received a copy of the GNU General Public License along with
11# this program; if not, write to the Free Software Foundation, Inc.,
12# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
13""" Copyright (c) 2002-2003 LOGILAB S.A. (Paris, FRANCE).
14 http://www.logilab.fr/ -- mailto:contact@logilab.fr
15 
16a generic visitor abstract implementation
17"""
18
19def no_filter(_):
20    return 1
21
22
23# Iterators ###################################################################
24class FilteredIterator(object):
25
26    def __init__(self, node, list_func, filter_func=None):
27        self._next = [(node, 0)]
28        if filter_func is None:
29            filter_func = no_filter
30        self._list = list_func(node, filter_func)
31       
32    def next(self):
33        try:
34            return self._list.pop(0)
35        except :
36            return None
37
38
39# Base Visitor ################################################################
40class Visitor(object):
41
42    def __init__(self, iterator_class, filter_func=None):
43        self._iter_class = iterator_class
44        self.filter = filter_func
45       
46    def visit(self, node, *args, **kargs):
47        """
48        launch the visit on a given node
49
50        call 'open_visit' before the begining of the visit, with extra args
51        given
52        when all nodes have been visited, call the 'close_visit' method
53        """
54        self.open_visit(node, *args, **kargs)
55        return self.close_visit(self._visit(node))
56
57    def _visit(self, node):
58        iterator = self._get_iterator(node)
59        n = iterator.next()
60        while n:
61            result = n.accept(self)
62            n = iterator.next()
63        return result
64
65    def _get_iterator(self, node):
66        return self._iter_class(node, self.filter)
67       
68    def open_visit(self, *args, **kargs):
69        """
70        method called at the beginning of the visit
71        """
72        pass
73   
74    def close_visit(self, result):
75        """
76        method called at the end of the visit
77        """
78        return result
79
80
81
82# standard visited mixin ######################################################
83class VisitedMixIn(object):
84    """
85    Visited interface allow node visitors to use the node
86    """
87    def get_visit_name(self):
88        """
89        return the visit name for the mixed class. When calling 'accept', the
90        method <'visit_' + name returned by this method> will be called on the
91        visitor
92        """
93        try:
94            return self.TYPE.replace('-', '_')
95        except:
96            return self.__class__.__name__.lower()
97   
98    def accept(self, visitor, *args, **kwargs):
99        func = getattr(visitor, 'visit_%s' % self.get_visit_name())
100        return func(self, *args, **kwargs)
101   
102    def leave(self, visitor, *args, **kwargs):
103        func = getattr(visitor, 'leave_%s' % self.get_visit_name())
104        return func(self, *args, **kwargs)
105
Note: See TracBrowser for help on using the browser.