Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: third_party/pylint/pyreverse/diadefslib.py

Issue 10447014: Add pylint to depot_tools. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix unittests. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/pylint/pyreverse/__init__.py ('k') | third_party/pylint/pyreverse/diagrams.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2000-2010 LOGILAB S.A. (Paris, FRANCE).
2 # http://www.logilab.fr/ -- mailto:contact@logilab.fr
3 #
4 # This program is free software; you can redistribute it and/or modify it under
5 # the terms of the GNU General Public License as published by the Free Software
6 # Foundation; either version 2 of the License, or (at your option) any later
7 # version.
8 #
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along with
14 # this program; if not, write to the Free Software Foundation, Inc.,
15 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 """handle diagram generation options for class diagram or default diagrams
17 """
18
19 from logilab.common.compat import builtins
20 BUILTINS_NAME = builtins.__name__
21 from logilab import astng
22 from logilab.astng.utils import LocalsVisitor
23
24 from pylint.pyreverse.diagrams import PackageDiagram, ClassDiagram
25
26 # diagram generators ##########################################################
27
28 class DiaDefGenerator:
29 """handle diagram generation options
30 """
31 def __init__(self, linker, handler):
32 """common Diagram Handler initialization"""
33 self.config = handler.config
34 self._set_default_options()
35 self.linker = linker
36 self.classdiagram = None # defined by subclasses
37
38 def get_title(self, node):
39 """get title for objects"""
40 title = node.name
41 if self.module_names:
42 title = '%s.%s' % (node.root().name, title)
43 return title
44
45 def _set_option(self, option):
46 """activate some options if not explicitly deactivated"""
47 # if we have a class diagram, we want more information by default;
48 # so if the option is None, we return True
49 if option is None:
50 if self.config.classes:
51 return True
52 else:
53 return False
54 return option
55
56 def _set_default_options(self):
57 """set different default options with _default dictionary"""
58 self.module_names = self._set_option(self.config.module_names)
59 all_ancestors = self._set_option(self.config.all_ancestors)
60 all_associated = self._set_option(self.config.all_associated)
61 anc_level, ass_level = (0, 0)
62 if all_ancestors:
63 anc_level = -1
64 if all_associated:
65 ass_level = -1
66 if self.config.show_ancestors is not None:
67 anc_level = self.config.show_ancestors
68 if self.config.show_associated is not None:
69 ass_level = self.config.show_associated
70 self.anc_level, self.ass_level = anc_level, ass_level
71
72 def _get_levels(self):
73 """help function for search levels"""
74 return self.anc_level, self.ass_level
75
76 def show_node(self, node):
77 """true if builtins and not show_builtins"""
78 if self.config.show_builtin:
79 return True
80 return node.root().name != BUILTINS_NAME
81
82 def add_class(self, node):
83 """visit one class and add it to diagram"""
84 self.linker.visit(node)
85 self.classdiagram.add_object(self.get_title(node), node)
86
87 def get_ancestors(self, node, level):
88 """return ancestor nodes of a class node"""
89 if level == 0:
90 return
91 for ancestor in node.ancestors(recurs=False):
92 if not self.show_node(ancestor):
93 continue
94 yield ancestor
95
96 def get_associated(self, klass_node, level):
97 """return associated nodes of a class node"""
98 if level == 0:
99 return
100 for ass_nodes in klass_node.instance_attrs_type.values() + \
101 klass_node.locals_type.values():
102 for ass_node in ass_nodes:
103 if isinstance(ass_node, astng.Instance):
104 ass_node = ass_node._proxied
105 if not (isinstance(ass_node, astng.Class)
106 and self.show_node(ass_node)):
107 continue
108 yield ass_node
109
110 def extract_classes(self, klass_node, anc_level, ass_level):
111 """extract recursively classes related to klass_node"""
112 if self.classdiagram.has_node(klass_node) or not self.show_node(klass_no de):
113 return
114 self.add_class(klass_node)
115
116 for ancestor in self.get_ancestors(klass_node, anc_level):
117 self.extract_classes(ancestor, anc_level-1, ass_level)
118
119 for ass_node in self.get_associated(klass_node, ass_level):
120 self.extract_classes(ass_node, anc_level, ass_level-1)
121
122
123 class DefaultDiadefGenerator(LocalsVisitor, DiaDefGenerator):
124 """generate minimum diagram definition for the project :
125
126 * a package diagram including project's modules
127 * a class diagram including project's classes
128 """
129
130 def __init__(self, linker, handler):
131 DiaDefGenerator.__init__(self, linker, handler)
132 LocalsVisitor.__init__(self)
133
134 def visit_project(self, node):
135 """visit an astng.Project node
136
137 create a diagram definition for packages
138 """
139 mode = self.config.mode
140 if len(node.modules) > 1:
141 self.pkgdiagram = PackageDiagram('packages %s' % node.name, mode)
142 else:
143 self.pkgdiagram = None
144 self.classdiagram = ClassDiagram('classes %s' % node.name, mode)
145
146 def leave_project(self, node):
147 """leave the astng.Project node
148
149 return the generated diagram definition
150 """
151 if self.pkgdiagram:
152 return self.pkgdiagram, self.classdiagram
153 return self.classdiagram,
154
155 def visit_module(self, node):
156 """visit an astng.Module node
157
158 add this class to the package diagram definition
159 """
160 if self.pkgdiagram:
161 self.linker.visit(node)
162 self.pkgdiagram.add_object(node.name, node)
163
164 def visit_class(self, node):
165 """visit an astng.Class node
166
167 add this class to the class diagram definition
168 """
169 anc_level, ass_level = self._get_levels()
170 self.extract_classes(node, anc_level, ass_level)
171
172 def visit_from(self, node):
173 """visit astng.From and catch modules for package diagram
174 """
175 if self.pkgdiagram:
176 self.pkgdiagram.add_from_depend(node, node.modname)
177
178
179 class ClassDiadefGenerator(DiaDefGenerator):
180 """generate a class diagram definition including all classes related to a
181 given class
182 """
183
184 def __init__(self, linker, handler):
185 DiaDefGenerator.__init__(self, linker, handler)
186
187 def class_diagram(self, project, klass):
188 """return a class diagram definition for the given klass and its
189 related klasses
190 """
191
192 self.classdiagram = ClassDiagram(klass, self.config.mode)
193 if len(project.modules) > 1:
194 module, klass = klass.rsplit('.', 1)
195 module = project.get_module(module)
196 else:
197 module = project.modules[0]
198 klass = klass.split('.')[-1]
199 klass = module.ilookup(klass).next()
200
201 anc_level, ass_level = self._get_levels()
202 self.extract_classes(klass, anc_level, ass_level)
203 return self.classdiagram
204
205 # diagram handler #############################################################
206
207 class DiadefsHandler:
208 """handle diagram definitions :
209
210 get it from user (i.e. xml files) or generate them
211 """
212
213 def __init__(self, config):
214 self.config = config
215
216 def get_diadefs(self, project, linker):
217 """get the diagrams configuration data
218 :param linker: astng.inspector.Linker(IdGeneratorMixIn, LocalsVisitor)
219 :param project: astng.manager.Project
220 """
221
222 # read and interpret diagram definitions (Diadefs)
223 diagrams = []
224 generator = ClassDiadefGenerator(linker, self)
225 for klass in self.config.classes:
226 diagrams.append(generator.class_diagram(project, klass))
227 if not diagrams:
228 diagrams = DefaultDiadefGenerator(linker, self).visit(project)
229 for diagram in diagrams:
230 diagram.extract_relationships()
231 return diagrams
OLDNEW
« no previous file with comments | « third_party/pylint/pyreverse/__init__.py ('k') | third_party/pylint/pyreverse/diagrams.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698