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

Unified Diff: tools/telemetry/third_party/rope/rope/base/oi/soi.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/soi.py
diff --git a/tools/telemetry/third_party/rope/rope/base/oi/soi.py b/tools/telemetry/third_party/rope/rope/base/oi/soi.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a11b5efdf30b218a926e54e4051151a4025f91a
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/base/oi/soi.py
@@ -0,0 +1,197 @@
+"""A module for inferring objects
+
+For more information see the documentation in `rope.base.oi`
+package.
+
+"""
+import rope.base.builtins
+import rope.base.pynames
+import rope.base.pyobjects
+from rope.base import evaluate, utils, arguments
+
+
+_ignore_inferred = utils.ignore_exception(
+ rope.base.pyobjects.IsBeingInferredError)
+
+
+@_ignore_inferred
+def infer_returned_object(pyfunction, args):
+ """Infer the `PyObject` this `PyFunction` returns after calling"""
+ object_info = pyfunction.pycore.object_info
+ result = object_info.get_exact_returned(pyfunction, args)
+ if result is not None:
+ return result
+ result = _infer_returned(pyfunction, args)
+ if result is not None:
+ if args and pyfunction.get_module().get_resource() is not None:
+ params = args.get_arguments(
+ pyfunction.get_param_names(special_args=False))
+ object_info.function_called(pyfunction, params, result)
+ return result
+ return object_info.get_returned(pyfunction, args)
+
+
+@_ignore_inferred
+def infer_parameter_objects(pyfunction):
+ """Infer the `PyObject`\s of parameters of this `PyFunction`"""
+ object_info = pyfunction.pycore.object_info
+ result = object_info.get_parameter_objects(pyfunction)
+ if result is None:
+ result = _parameter_objects(pyfunction)
+ _handle_first_parameter(pyfunction, result)
+ return result
+
+
+def _handle_first_parameter(pyobject, parameters):
+ kind = pyobject.get_kind()
+ if parameters is None or kind not in ['method', 'classmethod']:
+ pass
+ if not parameters:
+ if not pyobject.get_param_names(special_args=False):
+ return
+ parameters.append(rope.base.pyobjects.get_unknown())
+ if kind == 'method':
+ parameters[0] = rope.base.pyobjects.PyObject(pyobject.parent)
+ if kind == 'classmethod':
+ parameters[0] = pyobject.parent
+
+
+@_ignore_inferred
+def infer_assigned_object(pyname):
+ if not pyname.assignments:
+ return
+ for assignment in reversed(pyname.assignments):
+ result = _infer_assignment(assignment, pyname.module)
+ if result is not None:
+ return result
+
+
+def get_passed_objects(pyfunction, parameter_index):
+ object_info = pyfunction.pycore.object_info
+ result = object_info.get_passed_objects(pyfunction,
+ parameter_index)
+ if not result:
+ statically_inferred = _parameter_objects(pyfunction)
+ if len(statically_inferred) > parameter_index:
+ result.append(statically_inferred[parameter_index])
+ return result
+
+
+def _infer_returned(pyobject, args):
+ if args:
+ # HACK: Setting parameter objects manually
+ # This is not thread safe and might cause problems if `args`
+ # does not come from a good call site
+ pyobject.get_scope().invalidate_data()
+ pyobject._set_parameter_pyobjects(
+ args.get_arguments(pyobject.get_param_names(special_args=False)))
+ scope = pyobject.get_scope()
+ if not scope._get_returned_asts():
+ return
+ maxtries = 3
+ for returned_node in reversed(scope._get_returned_asts()[-maxtries:]):
+ try:
+ resulting_pyname = evaluate.eval_node(scope, returned_node)
+ if resulting_pyname is None:
+ continue
+ pyobject = resulting_pyname.get_object()
+ if pyobject == rope.base.pyobjects.get_unknown():
+ continue
+ if not scope._is_generator():
+ return pyobject
+ else:
+ return rope.base.builtins.get_generator(pyobject)
+ except rope.base.pyobjects.IsBeingInferredError:
+ pass
+
+
+def _parameter_objects(pyobject):
+ params = pyobject.get_param_names(special_args=False)
+ return [rope.base.pyobjects.get_unknown()] * len(params)
+
+# handling `rope.base.pynames.AssignmentValue`
+
+
+@_ignore_inferred
+def _infer_assignment(assignment, pymodule):
+ result = _follow_pyname(assignment, pymodule)
+ if result is None:
+ return None
+ pyname, pyobject = result
+ pyobject = _follow_evaluations(assignment, pyname, pyobject)
+ if pyobject is None:
+ return None
+ return _follow_levels(assignment, pyobject)
+
+
+def _follow_levels(assignment, pyobject):
+ for index in assignment.levels:
+ if isinstance(pyobject.get_type(), rope.base.builtins.Tuple):
+ holdings = pyobject.get_type().get_holding_objects()
+ if holdings:
+ pyobject = holdings[min(len(holdings) - 1, index)]
+ else:
+ pyobject = None
+ elif isinstance(pyobject.get_type(), rope.base.builtins.List):
+ pyobject = pyobject.get_type().holding
+ else:
+ pyobject = None
+ if pyobject is None:
+ break
+ return pyobject
+
+
+@_ignore_inferred
+def _follow_pyname(assignment, pymodule, lineno=None):
+ assign_node = assignment.ast_node
+ if lineno is None:
+ lineno = _get_lineno_for_node(assign_node)
+ holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
+ pyname = evaluate.eval_node(holding_scope, assign_node)
+ if pyname is not None:
+ result = pyname.get_object()
+ if isinstance(result.get_type(), rope.base.builtins.Property) and \
+ holding_scope.get_kind() == 'Class':
+ arg = rope.base.pynames.UnboundName(
+ rope.base.pyobjects.PyObject(holding_scope.pyobject))
+ return pyname, result.get_type().get_property_object(
+ arguments.ObjectArguments([arg]))
+ return pyname, result
+
+
+@_ignore_inferred
+def _follow_evaluations(assignment, pyname, pyobject):
+ new_pyname = pyname
+ tokens = assignment.evaluation.split('.')
+ for token in tokens:
+ call = token.endswith('()')
+ if call:
+ token = token[:-2]
+ if token:
+ pyname = new_pyname
+ new_pyname = _get_attribute(pyobject, token)
+ if new_pyname is not None:
+ pyobject = new_pyname.get_object()
+ if pyobject is not None and call:
+ if isinstance(pyobject, rope.base.pyobjects.AbstractFunction):
+ args = arguments.ObjectArguments([pyname])
+ pyobject = pyobject.get_returned_object(args)
+ else:
+ pyobject = None
+ if pyobject is None:
+ break
+ if pyobject is not None and assignment.assign_type:
+ return rope.base.pyobjects.PyObject(pyobject)
+ return pyobject
+
+
+def _get_lineno_for_node(assign_node):
+ if hasattr(assign_node, 'lineno') and \
+ assign_node.lineno is not None:
+ return assign_node.lineno
+ return 1
+
+
+def _get_attribute(pyobject, name):
+ if pyobject is not None and name in pyobject:
+ return pyobject[name]
« no previous file with comments | « tools/telemetry/third_party/rope/rope/base/oi/soa.py ('k') | tools/telemetry/third_party/rope/rope/base/oi/transform.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698