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

Unified Diff: tools/telemetry/third_party/rope/rope/base/oi/soa.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/base/oi/soa.py
diff --git a/tools/telemetry/third_party/rope/rope/base/oi/soa.py b/tools/telemetry/third_party/rope/rope/base/oi/soa.py
new file mode 100644
index 0000000000000000000000000000000000000000..a34b970ea2f599189ad959f7a97ad6e4a6ec8275
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/base/oi/soa.py
@@ -0,0 +1,139 @@
+import rope.base.ast
+import rope.base.oi.soi
+import rope.base.pynames
+from rope.base import pyobjects, evaluate, astutils, arguments
+
+
+def analyze_module(pycore, pymodule, should_analyze,
+ search_subscopes, followed_calls):
+ """Analyze `pymodule` for static object inference
+
+ Analyzes scopes for collecting object information. The analysis
+ starts from inner scopes.
+
+ """
+ _analyze_node(pycore, pymodule, should_analyze,
+ search_subscopes, followed_calls)
+
+
+def _analyze_node(pycore, pydefined, should_analyze,
+ search_subscopes, followed_calls):
+ if search_subscopes(pydefined):
+ for scope in pydefined.get_scope().get_scopes():
+ _analyze_node(pycore, scope.pyobject, should_analyze,
+ search_subscopes, followed_calls)
+ if should_analyze(pydefined):
+ new_followed_calls = max(0, followed_calls - 1)
+ return_true = lambda pydefined: True
+ return_false = lambda pydefined: False
+
+ def _follow(pyfunction):
+ _analyze_node(pycore, pyfunction, return_true,
+ return_false, new_followed_calls)
+
+ if not followed_calls:
+ _follow = None
+ visitor = SOAVisitor(pycore, pydefined, _follow)
+ for child in rope.base.ast.get_child_nodes(pydefined.get_ast()):
+ rope.base.ast.walk(child, visitor)
+
+
+class SOAVisitor(object):
+
+ def __init__(self, pycore, pydefined, follow_callback=None):
+ self.pycore = pycore
+ self.pymodule = pydefined.get_module()
+ self.scope = pydefined.get_scope()
+ self.follow = follow_callback
+
+ def _FunctionDef(self, node):
+ pass
+
+ def _ClassDef(self, node):
+ pass
+
+ def _Call(self, node):
+ for child in rope.base.ast.get_child_nodes(node):
+ rope.base.ast.walk(child, self)
+ primary, pyname = evaluate.eval_node2(self.scope, node.func)
+ if pyname is None:
+ return
+ pyfunction = pyname.get_object()
+ if isinstance(pyfunction, pyobjects.AbstractFunction):
+ args = arguments.create_arguments(primary, pyfunction,
+ node, self.scope)
+ elif isinstance(pyfunction, pyobjects.PyClass):
+ pyclass = pyfunction
+ if '__init__' in pyfunction:
+ pyfunction = pyfunction['__init__'].get_object()
+ pyname = rope.base.pynames.UnboundName(pyobjects.PyObject(pyclass))
+ args = self._args_with_self(primary, pyname, pyfunction, node)
+ elif '__call__' in pyfunction:
+ pyfunction = pyfunction['__call__'].get_object()
+ args = self._args_with_self(primary, pyname, pyfunction, node)
+ else:
+ return
+ self._call(pyfunction, args)
+
+ def _args_with_self(self, primary, self_pyname, pyfunction, node):
+ base_args = arguments.create_arguments(primary, pyfunction,
+ node, self.scope)
+ return arguments.MixedArguments(self_pyname, base_args, self.scope)
+
+ def _call(self, pyfunction, args):
+ if isinstance(pyfunction, pyobjects.PyFunction):
+ if self.follow is not None:
+ before = self._parameter_objects(pyfunction)
+ self.pycore.object_info.function_called(
+ pyfunction, args.get_arguments(pyfunction.get_param_names()))
+ pyfunction._set_parameter_pyobjects(None)
+ if self.follow is not None:
+ after = self._parameter_objects(pyfunction)
+ if after != before:
+ self.follow(pyfunction)
+ # XXX: Maybe we should not call every builtin function
+ if isinstance(pyfunction, rope.base.builtins.BuiltinFunction):
+ pyfunction.get_returned_object(args)
+
+ def _parameter_objects(self, pyfunction):
+ result = []
+ for i in range(len(pyfunction.get_param_names(False))):
+ result.append(pyfunction.get_parameter(i))
+ return result
+
+ def _Assign(self, node):
+ for child in rope.base.ast.get_child_nodes(node):
+ rope.base.ast.walk(child, self)
+ visitor = _SOAAssignVisitor()
+ nodes = []
+ for child in node.targets:
+ rope.base.ast.walk(child, visitor)
+ nodes.extend(visitor.nodes)
+ for subscript, levels in nodes:
+ instance = evaluate.eval_node(self.scope, subscript.value)
+ args_pynames = []
+ args_pynames.append(evaluate.eval_node(self.scope,
+ subscript.slice.value))
+ value = rope.base.oi.soi._infer_assignment(
+ rope.base.pynames.AssignmentValue(node.value, levels),
+ self.pymodule)
+ args_pynames.append(rope.base.pynames.UnboundName(value))
+ if instance is not None and value is not None:
+ pyobject = instance.get_object()
+ if '__setitem__' in pyobject:
+ pyfunction = pyobject['__setitem__'].get_object()
+ args = arguments.ObjectArguments([instance] + args_pynames)
+ self._call(pyfunction, args)
+ # IDEA: handle `__setslice__`, too
+
+
+class _SOAAssignVisitor(astutils._NodeNameCollector):
+
+ def __init__(self):
+ super(_SOAAssignVisitor, self).__init__()
+ self.nodes = []
+
+ def _added(self, node, levels):
+ if isinstance(node, rope.base.ast.Subscript) and \
+ isinstance(node.slice, rope.base.ast.Index):
+ self.nodes.append((node, levels))
« no previous file with comments | « tools/telemetry/third_party/rope/rope/base/oi/runmod.py ('k') | tools/telemetry/third_party/rope/rope/base/oi/soi.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698