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

Unified Diff: tools/telemetry/third_party/rope/rope/base/evaluate.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/evaluate.py
diff --git a/tools/telemetry/third_party/rope/rope/base/evaluate.py b/tools/telemetry/third_party/rope/rope/base/evaluate.py
new file mode 100644
index 0000000000000000000000000000000000000000..faf094075f6ce34770695fb25e4359c342fe7ef7
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/base/evaluate.py
@@ -0,0 +1,327 @@
+import rope.base.builtins
+import rope.base.pynames
+import rope.base.pyobjects
+from rope.base import ast, astutils, exceptions, pyobjects, arguments, worder
+
+
+BadIdentifierError = exceptions.BadIdentifierError
+
+
+def eval_location(pymodule, offset):
+ """Find the pyname at the offset"""
+ return eval_location2(pymodule, offset)[1]
+
+
+def eval_location2(pymodule, offset):
+ """Find the primary and pyname at offset"""
+ pyname_finder = ScopeNameFinder(pymodule)
+ return pyname_finder.get_primary_and_pyname_at(offset)
+
+
+def eval_node(scope, node):
+ """Evaluate a `ast.AST` node and return a PyName
+
+ Return `None` if the expression cannot be evaluated.
+ """
+ return eval_node2(scope, node)[1]
+
+
+def eval_node2(scope, node):
+ evaluator = StatementEvaluator(scope)
+ ast.walk(node, evaluator)
+ return evaluator.old_result, evaluator.result
+
+
+def eval_str(holding_scope, name):
+ return eval_str2(holding_scope, name)[1]
+
+
+def eval_str2(holding_scope, name):
+ try:
+ # parenthesizing for handling cases like 'a_var.\nattr'
+ node = ast.parse('(%s)' % name)
+ except SyntaxError:
+ raise BadIdentifierError(
+ 'Not a resolvable python identifier selected.')
+ return eval_node2(holding_scope, node)
+
+
+class ScopeNameFinder(object):
+
+ def __init__(self, pymodule):
+ self.module_scope = pymodule.get_scope()
+ self.lines = pymodule.lines
+ self.worder = worder.Worder(pymodule.source_code, True)
+
+ def _is_defined_in_class_body(self, holding_scope, offset, lineno):
+ if lineno == holding_scope.get_start() and \
+ holding_scope.parent is not None and \
+ holding_scope.parent.get_kind() == 'Class' and \
+ self.worder.is_a_class_or_function_name_in_header(offset):
+ return True
+ if lineno != holding_scope.get_start() and \
+ holding_scope.get_kind() == 'Class' and \
+ self.worder.is_name_assigned_in_class_body(offset):
+ return True
+ return False
+
+ def _is_function_name_in_function_header(self, scope, offset, lineno):
+ if scope.get_start() <= lineno <= scope.get_body_start() and \
+ scope.get_kind() == 'Function' and \
+ self.worder.is_a_class_or_function_name_in_header(offset):
+ return True
+ return False
+
+ def get_pyname_at(self, offset):
+ return self.get_primary_and_pyname_at(offset)[1]
+
+ def get_primary_and_pyname_at(self, offset):
+ lineno = self.lines.get_line_number(offset)
+ holding_scope = self.module_scope.get_inner_scope_for_line(lineno)
+ # function keyword parameter
+ if self.worder.is_function_keyword_parameter(offset):
+ keyword_name = self.worder.get_word_at(offset)
+ pyobject = self.get_enclosing_function(offset)
+ if isinstance(pyobject, pyobjects.PyFunction):
+ return (None,
+ pyobject.get_parameters().get(keyword_name, None))
+ # class body
+ if self._is_defined_in_class_body(holding_scope, offset, lineno):
+ class_scope = holding_scope
+ if lineno == holding_scope.get_start():
+ class_scope = holding_scope.parent
+ name = self.worder.get_primary_at(offset).strip()
+ try:
+ return (None, class_scope.pyobject[name])
+ except rope.base.exceptions.AttributeNotFoundError:
+ return (None, None)
+ # function header
+ if self._is_function_name_in_function_header(holding_scope,
+ offset, lineno):
+ name = self.worder.get_primary_at(offset).strip()
+ return (None, holding_scope.parent[name])
+ # from statement module
+ if self.worder.is_from_statement_module(offset):
+ module = self.worder.get_primary_at(offset)
+ module_pyname = self._find_module(module)
+ return (None, module_pyname)
+ if self.worder.is_from_aliased(offset):
+ name = self.worder.get_from_aliased(offset)
+ else:
+ name = self.worder.get_primary_at(offset)
+ return eval_str2(holding_scope, name)
+
+ def get_enclosing_function(self, offset):
+ function_parens = self.worder.find_parens_start_from_inside(offset)
+ try:
+ function_pyname = self.get_pyname_at(function_parens - 1)
+ except BadIdentifierError:
+ function_pyname = None
+ if function_pyname is not None:
+ pyobject = function_pyname.get_object()
+ if isinstance(pyobject, pyobjects.AbstractFunction):
+ return pyobject
+ elif isinstance(pyobject, pyobjects.AbstractClass) and \
+ '__init__' in pyobject:
+ return pyobject['__init__'].get_object()
+ elif '__call__' in pyobject:
+ return pyobject['__call__'].get_object()
+ return None
+
+ def _find_module(self, module_name):
+ dots = 0
+ while module_name[dots] == '.':
+ dots += 1
+ return rope.base.pynames.ImportedModule(
+ self.module_scope.pyobject, module_name[dots:], dots)
+
+
+class StatementEvaluator(object):
+
+ def __init__(self, scope):
+ self.scope = scope
+ self.result = None
+ self.old_result = None
+
+ def _Name(self, node):
+ self.result = self.scope.lookup(node.id)
+
+ def _Attribute(self, node):
+ pyname = eval_node(self.scope, node.value)
+ if pyname is None:
+ pyname = rope.base.pynames.UnboundName()
+ self.old_result = pyname
+ if pyname.get_object() != rope.base.pyobjects.get_unknown():
+ try:
+ self.result = pyname.get_object()[node.attr]
+ except exceptions.AttributeNotFoundError:
+ self.result = None
+
+ def _Call(self, node):
+ primary, pyobject = self._get_primary_and_object_for_node(node.func)
+ if pyobject is None:
+ return
+
+ def _get_returned(pyobject):
+ args = arguments.create_arguments(primary, pyobject,
+ node, self.scope)
+ return pyobject.get_returned_object(args)
+ if isinstance(pyobject, rope.base.pyobjects.AbstractClass):
+ result = None
+ if '__new__' in pyobject:
+ new_function = pyobject['__new__'].get_object()
+ result = _get_returned(new_function)
+ if result is None or \
+ result == rope.base.pyobjects.get_unknown():
+ result = rope.base.pyobjects.PyObject(pyobject)
+ self.result = rope.base.pynames.UnboundName(pyobject=result)
+ return
+
+ pyfunction = None
+ if isinstance(pyobject, rope.base.pyobjects.AbstractFunction):
+ pyfunction = pyobject
+ elif '__call__' in pyobject:
+ pyfunction = pyobject['__call__'].get_object()
+ if pyfunction is not None:
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=_get_returned(pyfunction))
+
+ def _Str(self, node):
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_str())
+
+ def _Num(self, node):
+ type_name = type(node.n).__name__
+ self.result = self._get_builtin_name(type_name)
+
+ def _get_builtin_name(self, type_name):
+ pytype = rope.base.builtins.builtins[type_name].get_object()
+ return rope.base.pynames.UnboundName(
+ rope.base.pyobjects.PyObject(pytype))
+
+ def _BinOp(self, node):
+ self.result = rope.base.pynames.UnboundName(
+ self._get_object_for_node(node.left))
+
+ def _BoolOp(self, node):
+ pyobject = self._get_object_for_node(node.values[0])
+ if pyobject is None:
+ pyobject = self._get_object_for_node(node.values[1])
+ self.result = rope.base.pynames.UnboundName(pyobject)
+
+ def _Repr(self, node):
+ self.result = self._get_builtin_name('str')
+
+ def _UnaryOp(self, node):
+ self.result = rope.base.pynames.UnboundName(
+ self._get_object_for_node(node.operand))
+
+ def _Compare(self, node):
+ self.result = self._get_builtin_name('bool')
+
+ def _Dict(self, node):
+ keys = None
+ values = None
+ if node.keys:
+ keys = self._get_object_for_node(node.keys[0])
+ values = self._get_object_for_node(node.values[0])
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_dict(keys, values))
+
+ def _List(self, node):
+ holding = None
+ if node.elts:
+ holding = self._get_object_for_node(node.elts[0])
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_list(holding))
+
+ def _ListComp(self, node):
+ pyobject = self._what_does_comprehension_hold(node)
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_list(pyobject))
+
+ def _GeneratorExp(self, node):
+ pyobject = self._what_does_comprehension_hold(node)
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_iterator(pyobject))
+
+ def _what_does_comprehension_hold(self, node):
+ scope = self._make_comprehension_scope(node)
+ pyname = eval_node(scope, node.elt)
+ return pyname.get_object() if pyname is not None else None
+
+ def _make_comprehension_scope(self, node):
+ scope = self.scope
+ module = scope.pyobject.get_module()
+ names = {}
+ for comp in node.generators:
+ new_names = _get_evaluated_names(comp.target, comp.iter, module,
+ '.__iter__().next()', node.lineno)
+ names.update(new_names)
+ return rope.base.pyscopes.TemporaryScope(scope.pycore, scope, names)
+
+ def _Tuple(self, node):
+ objects = []
+ if len(node.elts) < 4:
+ for stmt in node.elts:
+ pyobject = self._get_object_for_node(stmt)
+ objects.append(pyobject)
+ else:
+ objects.append(self._get_object_for_node(node.elts[0]))
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.get_tuple(*objects))
+
+ def _get_object_for_node(self, stmt):
+ pyname = eval_node(self.scope, stmt)
+ pyobject = None
+ if pyname is not None:
+ pyobject = pyname.get_object()
+ return pyobject
+
+ def _get_primary_and_object_for_node(self, stmt):
+ primary, pyname = eval_node2(self.scope, stmt)
+ pyobject = None
+ if pyname is not None:
+ pyobject = pyname.get_object()
+ return primary, pyobject
+
+ def _Subscript(self, node):
+ if isinstance(node.slice, ast.Index):
+ self._call_function(node.value, '__getitem__',
+ [node.slice.value])
+ elif isinstance(node.slice, ast.Slice):
+ self._call_function(node.value, '__getslice__')
+
+ def _call_function(self, node, function_name, other_args=None):
+ pyname = eval_node(self.scope, node)
+ if pyname is not None:
+ pyobject = pyname.get_object()
+ else:
+ return
+ if function_name in pyobject:
+ called = pyobject[function_name].get_object()
+ if not called or \
+ not isinstance(called, pyobjects.AbstractFunction):
+ return
+ args = [node]
+ if other_args:
+ args += other_args
+ arguments_ = arguments.Arguments(args, self.scope)
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=called.get_returned_object(arguments_))
+
+ def _Lambda(self, node):
+ self.result = rope.base.pynames.UnboundName(
+ pyobject=rope.base.builtins.Lambda(node, self.scope))
+
+
+def _get_evaluated_names(targets, assigned, module, evaluation, lineno):
+ result = {}
+ for name, levels in astutils.get_name_levels(targets):
+ assignment = rope.base.pynames.AssignmentValue(assigned, levels,
+ evaluation)
+ # XXX: this module should not access `rope.base.pynamesdef`!
+ pyname = rope.base.pynamesdef.AssignedName(lineno, module)
+ pyname.assignments.append(assignment)
+ result[name] = pyname
+ return result
« no previous file with comments | « tools/telemetry/third_party/rope/rope/base/default_config.py ('k') | tools/telemetry/third_party/rope/rope/base/exceptions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698