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

Side by Side Diff: third_party/logilab/astng/inspector.py

Issue 739393004: Revert "Revert "pylint: upgrade to 1.3.1"" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 6 years 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/logilab/astng/inference.py ('k') | third_party/logilab/astng/manager.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 # This program is free software; you can redistribute it and/or modify it under
2 # the terms of the GNU Lesser General Public License as published by the Free So ftware
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 Lesser General Public License for more d etails.
9 #
10 # You should have received a copy of the GNU Lesser 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 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
14 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
15 # copyright 2003-2010 Sylvain Thenault, all rights reserved.
16 # contact mailto:thenault@gmail.com
17 #
18 # This file is part of logilab-astng.
19 #
20 # logilab-astng is free software: you can redistribute it and/or modify it
21 # under the terms of the GNU Lesser General Public License as published by the
22 # Free Software Foundation, either version 2.1 of the License, or (at your
23 # option) any later version.
24 #
25 # logilab-astng is distributed in the hope that it will be useful, but
26 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
28 # for more details.
29 #
30 # You should have received a copy of the GNU Lesser General Public License along
31 # with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
32 """visitor doing some postprocessing on the astng tree.
33 Try to resolve definitions (namespace) dictionary, relationship...
34
35 This module has been imported from pyreverse
36 """
37
38 __docformat__ = "restructuredtext en"
39
40 from os.path import dirname
41
42 from logilab.common.modutils import get_module_part, is_relative, \
43 is_standard_module
44
45 from logilab import astng
46 from logilab.astng.exceptions import InferenceError
47 from logilab.astng.utils import LocalsVisitor
48
49 class IdGeneratorMixIn:
50 """
51 Mixin adding the ability to generate integer uid
52 """
53 def __init__(self, start_value=0):
54 self.id_count = start_value
55
56 def init_counter(self, start_value=0):
57 """init the id counter
58 """
59 self.id_count = start_value
60
61 def generate_id(self):
62 """generate a new identifier
63 """
64 self.id_count += 1
65 return self.id_count
66
67
68 class Linker(IdGeneratorMixIn, LocalsVisitor):
69 """
70 walk on the project tree and resolve relationships.
71
72 According to options the following attributes may be added to visited nodes:
73
74 * uid,
75 a unique identifier for the node (on astng.Project, astng.Module,
76 astng.Class and astng.locals_type). Only if the linker has been instantiat ed
77 with tag=True parameter (False by default).
78
79 * Function
80 a mapping from locals names to their bounded value, which may be a
81 constant like a string or an integer, or an astng node (on astng.Module,
82 astng.Class and astng.Function).
83
84 * instance_attrs_type
85 as locals_type but for klass member attributes (only on astng.Class)
86
87 * implements,
88 list of implemented interface _objects_ (only on astng.Class nodes)
89 """
90
91 def __init__(self, project, inherited_interfaces=0, tag=False):
92 IdGeneratorMixIn.__init__(self)
93 LocalsVisitor.__init__(self)
94 # take inherited interface in consideration or not
95 self.inherited_interfaces = inherited_interfaces
96 # tag nodes or not
97 self.tag = tag
98 # visited project
99 self.project = project
100
101
102 def visit_project(self, node):
103 """visit an astng.Project node
104
105 * optionally tag the node with a unique id
106 """
107 if self.tag:
108 node.uid = self.generate_id()
109 for module in node.modules:
110 self.visit(module)
111
112 def visit_package(self, node):
113 """visit an astng.Package node
114
115 * optionally tag the node with a unique id
116 """
117 if self.tag:
118 node.uid = self.generate_id()
119 for subelmt in node.values():
120 self.visit(subelmt)
121
122 def visit_module(self, node):
123 """visit an astng.Module node
124
125 * set the locals_type mapping
126 * set the depends mapping
127 * optionally tag the node with a unique id
128 """
129 if hasattr(node, 'locals_type'):
130 return
131 node.locals_type = {}
132 node.depends = []
133 if self.tag:
134 node.uid = self.generate_id()
135
136 def visit_class(self, node):
137 """visit an astng.Class node
138
139 * set the locals_type and instance_attrs_type mappings
140 * set the implements list and build it
141 * optionally tag the node with a unique id
142 """
143 if hasattr(node, 'locals_type'):
144 return
145 node.locals_type = {}
146 if self.tag:
147 node.uid = self.generate_id()
148 # resolve ancestors
149 for baseobj in node.ancestors(recurs=False):
150 specializations = getattr(baseobj, 'specializations', [])
151 specializations.append(node)
152 baseobj.specializations = specializations
153 # resolve instance attributes
154 node.instance_attrs_type = {}
155 for assattrs in node.instance_attrs.values():
156 for assattr in assattrs:
157 self.handle_assattr_type(assattr, node)
158 # resolve implemented interface
159 try:
160 node.implements = list(node.interfaces(self.inherited_interfaces))
161 except InferenceError:
162 node.implements = ()
163
164 def visit_function(self, node):
165 """visit an astng.Function node
166
167 * set the locals_type mapping
168 * optionally tag the node with a unique id
169 """
170 if hasattr(node, 'locals_type'):
171 return
172 node.locals_type = {}
173 if self.tag:
174 node.uid = self.generate_id()
175
176 link_project = visit_project
177 link_module = visit_module
178 link_class = visit_class
179 link_function = visit_function
180
181 def visit_assname(self, node):
182 """visit an astng.AssName node
183
184 handle locals_type
185 """
186 # avoid double parsing done by different Linkers.visit
187 # running over the same project:
188 if hasattr(node, '_handled'):
189 return
190 node._handled = True
191 if node.name in node.frame():
192 frame = node.frame()
193 else:
194 # the name has been defined as 'global' in the frame and belongs
195 # there. Btw the frame is not yet visited as the name is in the
196 # root locals; the frame hence has no locals_type attribute
197 frame = node.root()
198 try:
199 values = node.infered()
200 try:
201 already_infered = frame.locals_type[node.name]
202 for valnode in values:
203 if not valnode in already_infered:
204 already_infered.append(valnode)
205 except KeyError:
206 frame.locals_type[node.name] = values
207 except astng.InferenceError:
208 pass
209
210 def handle_assattr_type(self, node, parent):
211 """handle an astng.AssAttr node
212
213 handle instance_attrs_type
214 """
215 try:
216 values = list(node.infer())
217 try:
218 already_infered = parent.instance_attrs_type[node.attrname]
219 for valnode in values:
220 if not valnode in already_infered:
221 already_infered.append(valnode)
222 except KeyError:
223 parent.instance_attrs_type[node.attrname] = values
224 except astng.InferenceError:
225 pass
226
227 def visit_import(self, node):
228 """visit an astng.Import node
229
230 resolve module dependencies
231 """
232 context_file = node.root().file
233 for name in node.names:
234 relative = is_relative(name[0], context_file)
235 self._imported_module(node, name[0], relative)
236
237
238 def visit_from(self, node):
239 """visit an astng.From node
240
241 resolve module dependencies
242 """
243 basename = node.modname
244 context_file = node.root().file
245 if context_file is not None:
246 relative = is_relative(basename, context_file)
247 else:
248 relative = False
249 for name in node.names:
250 if name[0] == '*':
251 continue
252 # analyze dependencies
253 fullname = '%s.%s' % (basename, name[0])
254 if fullname.find('.') > -1:
255 try:
256 # XXX: don't use get_module_part, missing package precedence
257 fullname = get_module_part(fullname)
258 except ImportError:
259 continue
260 if fullname != basename:
261 self._imported_module(node, fullname, relative)
262
263
264 def compute_module(self, context_name, mod_path):
265 """return true if the module should be added to dependencies"""
266 package_dir = dirname(self.project.path)
267 if context_name == mod_path:
268 return 0
269 elif is_standard_module(mod_path, (package_dir,)):
270 return 1
271 return 0
272
273 # protected methods ########################################################
274
275 def _imported_module(self, node, mod_path, relative):
276 """notify an imported module, used to analyze dependencies
277 """
278 module = node.root()
279 context_name = module.name
280 if relative:
281 mod_path = '%s.%s' % ('.'.join(context_name.split('.')[:-1]),
282 mod_path)
283 if self.compute_module(context_name, mod_path):
284 # handle dependencies
285 if not hasattr(module, 'depends'):
286 module.depends = []
287 mod_paths = module.depends
288 if not mod_path in mod_paths:
289 mod_paths.append(mod_path)
OLDNEW
« no previous file with comments | « third_party/logilab/astng/inference.py ('k') | third_party/logilab/astng/manager.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698