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

Unified Diff: tools/telemetry/third_party/rope/rope/contrib/finderrors.py

Issue 1132103009: Example of refactoring using rope library. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/rope/rope/contrib/finderrors.py
diff --git a/tools/telemetry/third_party/rope/rope/contrib/finderrors.py b/tools/telemetry/third_party/rope/rope/contrib/finderrors.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ee7dd15f97a738ec757c17aaf5637aade9bcf4a
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/contrib/finderrors.py
@@ -0,0 +1,91 @@
+"""Finding bad name and attribute accesses
+
+`find_errors` function can be used to find possible bad name and
+attribute accesses. As an example::
+
+ errors = find_errors(project, project.get_resource('mod.py'))
+ for error in errors:
+ print '%s: %s' % (error.lineno, error.error)
+
+prints possible errors for ``mod.py`` file.
+
+TODO:
+
+* use task handles
+* reporting names at most once
+* attributes of extension modules that don't appear in
+ extension_modules project config can be ignored
+* not calling `PyScope.get_inner_scope_for_line()` if it is a
+ bottleneck; needs profiling
+* not reporting occurrences where rope cannot infer the object
+* rope saves multiple objects for some of the names in its objectdb
+ use all of them not to give false positives
+* ... ;-)
+
+"""
+from rope.base import ast, evaluate, pyobjects
+
+
+def find_errors(project, resource):
+ """Find possible bad name and attribute accesses
+
+ It returns a list of `Error`\s.
+ """
+ pymodule = project.get_pymodule(resource)
+ finder = _BadAccessFinder(pymodule)
+ ast.walk(pymodule.get_ast(), finder)
+ return finder.errors
+
+
+class _BadAccessFinder(object):
+
+ def __init__(self, pymodule):
+ self.pymodule = pymodule
+ self.scope = pymodule.get_scope()
+ self.errors = []
+
+ def _Name(self, node):
+ if isinstance(node.ctx, (ast.Store, ast.Param)):
+ return
+ scope = self.scope.get_inner_scope_for_line(node.lineno)
+ pyname = scope.lookup(node.id)
+ if pyname is None:
+ self._add_error(node, 'Unresolved variable')
+ elif self._is_defined_after(scope, pyname, node.lineno):
+ self._add_error(node, 'Defined later')
+
+ def _Attribute(self, node):
+ if not isinstance(node.ctx, ast.Store):
+ scope = self.scope.get_inner_scope_for_line(node.lineno)
+ pyname = evaluate.eval_node(scope, node.value)
+ if pyname is not None and \
+ pyname.get_object() != pyobjects.get_unknown():
+ if node.attr not in pyname.get_object():
+ self._add_error(node, 'Unresolved attribute')
+ ast.walk(node.value, self)
+
+ def _add_error(self, node, msg):
+ if isinstance(node, ast.Attribute):
+ name = node.attr
+ else:
+ name = node.id
+ if name != 'None':
+ error = Error(node.lineno, msg + ' ' + name)
+ self.errors.append(error)
+
+ def _is_defined_after(self, scope, pyname, lineno):
+ location = pyname.get_definition_location()
+ if location is not None and location[1] is not None:
+ if location[0] == self.pymodule and \
+ lineno <= location[1] <= scope.get_end():
+ return True
+
+
+class Error(object):
+
+ def __init__(self, lineno, error):
+ self.lineno = lineno
+ self.error = error
+
+ def __str__(self):
+ return '%s: %s' % (self.lineno, self.error)
« no previous file with comments | « tools/telemetry/third_party/rope/rope/contrib/codeassist.py ('k') | tools/telemetry/third_party/rope/rope/contrib/findit.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698