10
13
# You should have received a copy of the GNU General Public License along with
11
14
# this program; if not, write to the Free Software Foundation, Inc.,
12
15
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13
""" Copyright (c) 2002-2004 LOGILAB S.A. (Paris, FRANCE).
14
http://www.logilab.fr/ -- mailto:contact@logilab.fr
16
check for signs of poor design
16
"""check for signs of poor design
19
19
see http://intranet.logilab.fr/jpl/view?rql=Any%20X%20where%20X%20eid%201243
20
20
FIXME: missing 13, 15, 16
23
__revision__ = "$Id: design_analysis.py,v 1.7 2005/01/19 16:09:45 syt Exp $"
25
from logilab.common.astng import Function
26
from logilab.common.astng.utils import get_interfaces
28
from logilab.pylint.interfaces import IASTNGChecker
29
from logilab.pylint.checkers import BaseChecker
30
from logilab.pylint.checkers.utils import is_interface, is_exception, \
31
is_abstract, is_metaclass
23
__revision__ = "$Id: design_analysis.py,v 1.11 2005-12-30 15:41:29 adim Exp $"
25
from logilab.astng import Function, InferenceError
27
from pylint.interfaces import IASTNGChecker
28
from pylint.checkers import BaseChecker
33
30
def class_is_abstract(klass):
34
"""return true if the given class node should be considered as an abstrac
31
"""return true if the given class node should be considered as an abstract
37
for attr in klass.locals.values():
34
for attr in klass.values():
38
35
if isinstance(attr, Function):
39
if is_abstract(attr, pass_is_abstract=False):
36
if attr.is_abstract(pass_is_abstract=False):
45
42
'R0901': ('Too many ancestors (%s/%s)',
46
'Used when class has too many parent classes.'),
43
'Used when class has too many parent classes, try to reduce \
44
this to get a more simple (and so easier to use) class.'),
47
45
'R0902': ('Too many instance attributes (%s/%s)',
48
'Used when class has too many instance attributes.'),
49
'R0903': ('Not enough public methods (%s/%s)',
50
'Used when class has not enough public methods.'),
46
'Used when class has too many instance attributes, try to reduce \
47
this to get a more simple (and so easier to use) class.'),
48
'R0903': ('To few public methods (%s/%s)',
49
'Used when class has to few public methods, so be sure it\'s \
51
51
'R0904': ('Too many public methods (%s/%s)',
52
'Used when class has too many public methods.'),
52
'Used when class has too many public methods, try to reduce \
53
this to get a more simple (and so easier to use) class.'),
54
55
'R0911': ('Too many return statements (%s/%s)',
55
'Used when a function or method has too many return statement.'),
56
'Used when a function or method has too many return statement, \
57
making it hard to follow.'),
56
58
'R0912': ('Too many branches (%s/%s)',
57
'Used when a function or method has too many branches.'),
59
'Used when a function or method has too many branches, \
60
making it hard to follow.'),
58
61
'R0913': ('Too many arguments (%s/%s)',
59
62
'Used when a function or method takes too many arguments.'),
60
63
'R0914': ('Too many local variables (%s/%s)',
190
193
# update abstract / interface classes structures
191
194
if class_is_abstract(node):
192
195
self._abstracts.append(node)
193
elif is_interface(node) and node.name != 'Interface':
196
elif node.type == 'interface' and node.name != 'Interface':
194
197
self._ifaces.append(node)
195
198
for parent in node.ancestors(False):
196
199
if parent.name == 'Interface':
198
201
self._used_ifaces[parent] = 1
199
for iface in get_interfaces(node):
200
self._used_ifaces[iface] = 1
203
for iface in node.interfaces():
204
self._used_ifaces[iface] = 1
205
except InferenceError:
201
208
for parent in node.ancestors():
203
210
self._used_abstracts[parent] += 1