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

Unified Diff: tools/telemetry/third_party/rope/rope/base/pyobjectsdef.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/pyobjectsdef.py
diff --git a/tools/telemetry/third_party/rope/rope/base/pyobjectsdef.py b/tools/telemetry/third_party/rope/rope/base/pyobjectsdef.py
new file mode 100644
index 0000000000000000000000000000000000000000..5968ff854a4ed03b057ad1d037c9ecb343539fb1
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/base/pyobjectsdef.py
@@ -0,0 +1,549 @@
+import rope.base.codeanalyze
+import rope.base.evaluate
+import rope.base.builtins
+import rope.base.oi.soi
+import rope.base.pyscopes
+import rope.base.libutils
+from rope.base import (pynamesdef as pynames, exceptions, ast,
+ astutils, pyobjects, fscommands, arguments, utils)
+
+
+try:
+ unicode
+except NameError:
+ unicode = str
+
+class PyFunction(pyobjects.PyFunction):
+
+ def __init__(self, pycore, ast_node, parent):
+ rope.base.pyobjects.AbstractFunction.__init__(self)
+ rope.base.pyobjects.PyDefinedObject.__init__(
+ self, pycore, ast_node, parent)
+ self.arguments = self.ast_node.args
+ self.parameter_pyobjects = pynames._Inferred(
+ self._infer_parameters, self.get_module()._get_concluded_data())
+ self.returned = pynames._Inferred(self._infer_returned)
+ self.parameter_pynames = None
+
+ def _create_structural_attributes(self):
+ return {}
+
+ def _create_concluded_attributes(self):
+ return {}
+
+ def _create_scope(self):
+ return rope.base.pyscopes.FunctionScope(self.pycore, self,
+ _FunctionVisitor)
+
+ def _infer_parameters(self):
+ pyobjects = rope.base.oi.soi.infer_parameter_objects(self)
+ self._handle_special_args(pyobjects)
+ return pyobjects
+
+ def _infer_returned(self, args=None):
+ return rope.base.oi.soi.infer_returned_object(self, args)
+
+ def _handle_special_args(self, pyobjects):
+ if len(pyobjects) == len(self.arguments.args):
+ if self.arguments.vararg:
+ pyobjects.append(rope.base.builtins.get_list())
+ if self.arguments.kwarg:
+ pyobjects.append(rope.base.builtins.get_dict())
+
+ def _set_parameter_pyobjects(self, pyobjects):
+ if pyobjects is not None:
+ self._handle_special_args(pyobjects)
+ self.parameter_pyobjects.set(pyobjects)
+
+ def get_parameters(self):
+ if self.parameter_pynames is None:
+ result = {}
+ for index, name in enumerate(self.get_param_names()):
+ # TODO: handle tuple parameters
+ result[name] = pynames.ParameterName(self, index)
+ self.parameter_pynames = result
+ return self.parameter_pynames
+
+ def get_parameter(self, index):
+ if index < len(self.parameter_pyobjects.get()):
+ return self.parameter_pyobjects.get()[index]
+
+ def get_returned_object(self, args):
+ return self.returned.get(args)
+
+ def get_name(self):
+ return self.get_ast().name
+
+ def get_param_names(self, special_args=True):
+ # TODO: handle tuple parameters
+ result = [node.id for node in self.arguments.args
+ if isinstance(node, ast.Name)]
+ if special_args:
+ if self.arguments.vararg:
+ result.append(self.arguments.vararg)
+ if self.arguments.kwarg:
+ result.append(self.arguments.kwarg)
+ return result
+
+ def get_kind(self):
+ """Get function type
+
+ It returns one of 'function', 'method', 'staticmethod' or
+ 'classmethod' strs.
+
+ """
+ scope = self.parent.get_scope()
+ if isinstance(self.parent, PyClass):
+ for decorator in self.decorators:
+ pyname = rope.base.evaluate.eval_node(scope, decorator)
+ if pyname == rope.base.builtins.builtins['staticmethod']:
+ return 'staticmethod'
+ if pyname == rope.base.builtins.builtins['classmethod']:
+ return 'classmethod'
+ return 'method'
+ return 'function'
+
+ @property
+ def decorators(self):
+ try:
+ return getattr(self.ast_node, 'decorator_list')
+ except AttributeError:
+ return getattr(self.ast_node, 'decorators', None)
+
+
+class PyClass(pyobjects.PyClass):
+
+ def __init__(self, pycore, ast_node, parent):
+ self.visitor_class = _ClassVisitor
+ rope.base.pyobjects.AbstractClass.__init__(self)
+ rope.base.pyobjects.PyDefinedObject.__init__(
+ self, pycore, ast_node, parent)
+ self.parent = parent
+ self._superclasses = self.get_module()._get_concluded_data()
+
+ def get_superclasses(self):
+ if self._superclasses.get() is None:
+ self._superclasses.set(self._get_bases())
+ return self._superclasses.get()
+
+ def get_name(self):
+ return self.get_ast().name
+
+ def _create_concluded_attributes(self):
+ result = {}
+ for base in reversed(self.get_superclasses()):
+ result.update(base.get_attributes())
+ return result
+
+ def _get_bases(self):
+ result = []
+ for base_name in self.ast_node.bases:
+ base = rope.base.evaluate.eval_node(self.parent.get_scope(),
+ base_name)
+ if base is not None and \
+ base.get_object().get_type() == \
+ rope.base.pyobjects.get_base_type('Type'):
+ result.append(base.get_object())
+ return result
+
+ def _create_scope(self):
+ return rope.base.pyscopes.ClassScope(self.pycore, self)
+
+
+class PyModule(pyobjects.PyModule):
+
+ def __init__(self, pycore, source=None,
+ resource=None, force_errors=False):
+ ignore = pycore.project.prefs.get('ignore_syntax_errors', False)
+ syntax_errors = force_errors or not ignore
+ self.has_errors = False
+ try:
+ source, node = self._init_source(pycore, source, resource)
+ except exceptions.ModuleSyntaxError:
+ self.has_errors = True
+ if syntax_errors:
+ raise
+ else:
+ source = '\n'
+ node = ast.parse('\n')
+ self.source_code = source
+ self.star_imports = []
+ self.visitor_class = _GlobalVisitor
+ self.coding = fscommands.read_str_coding(self.source_code)
+ super(PyModule, self).__init__(pycore, node, resource)
+
+ def _init_source(self, pycore, source_code, resource):
+ filename = 'string'
+ if resource:
+ filename = resource.path
+ try:
+ if source_code is None:
+ source_bytes = resource.read_bytes()
+ source_code = fscommands.file_data_to_unicode(source_bytes)
+ else:
+ if isinstance(source_code, unicode):
+ source_bytes = fscommands.unicode_to_file_data(source_code)
+ else:
+ source_bytes = source_code
+ ast_node = ast.parse(source_bytes, filename=filename)
+ except SyntaxError as e:
+ raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg)
+ except UnicodeDecodeError as e:
+ raise exceptions.ModuleSyntaxError(filename, 1, '%s' % (e.reason))
+ return source_code, ast_node
+
+ @utils.prevent_recursion(lambda: {})
+ def _create_concluded_attributes(self):
+ result = {}
+ for star_import in self.star_imports:
+ result.update(star_import.get_names())
+ return result
+
+ def _create_scope(self):
+ return rope.base.pyscopes.GlobalScope(self.pycore, self)
+
+ @property
+ @utils.saveit
+ def lines(self):
+ """A `SourceLinesAdapter`"""
+ return rope.base.codeanalyze.SourceLinesAdapter(self.source_code)
+
+ @property
+ @utils.saveit
+ def logical_lines(self):
+ """A `LogicalLinesFinder`"""
+ return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines)
+
+
+class PyPackage(pyobjects.PyPackage):
+
+ def __init__(self, pycore, resource=None, force_errors=False):
+ self.resource = resource
+ init_dot_py = self._get_init_dot_py()
+ if init_dot_py is not None:
+ ast_node = pycore.project.get_pymodule(
+ init_dot_py, force_errors=force_errors).get_ast()
+ else:
+ ast_node = ast.parse('\n')
+ super(PyPackage, self).__init__(pycore, ast_node, resource)
+
+ def _create_structural_attributes(self):
+ result = {}
+ modname = rope.base.libutils.modname(self.resource)
+ extension_submodules = self.pycore._builtin_submodules(modname)
+ for name, module in extension_submodules.items():
+ result[name] = rope.base.builtins.BuiltinName(module)
+ if self.resource is None:
+ return result
+ for name, resource in self._get_child_resources().items():
+ result[name] = pynames.ImportedModule(self, resource=resource)
+ return result
+
+ def _create_concluded_attributes(self):
+ result = {}
+ init_dot_py = self._get_init_dot_py()
+ if init_dot_py:
+ init_object = self.pycore.project.get_pymodule(init_dot_py)
+ result.update(init_object.get_attributes())
+ return result
+
+ def _get_child_resources(self):
+ result = {}
+ for child in self.resource.get_children():
+ if child.is_folder():
+ result[child.name] = child
+ elif child.name.endswith('.py') and \
+ child.name != '__init__.py':
+ name = child.name[:-3]
+ result[name] = child
+ return result
+
+ def _get_init_dot_py(self):
+ if self.resource is not None and \
+ self.resource.has_child('__init__.py'):
+ return self.resource.get_child('__init__.py')
+ else:
+ return None
+
+ def _create_scope(self):
+ return self.get_module().get_scope()
+
+ def get_module(self):
+ init_dot_py = self._get_init_dot_py()
+ if init_dot_py:
+ return self.pycore.project.get_pymodule(init_dot_py)
+ return self
+
+
+class _AssignVisitor(object):
+
+ def __init__(self, scope_visitor):
+ self.scope_visitor = scope_visitor
+ self.assigned_ast = None
+
+ def _Assign(self, node):
+ self.assigned_ast = node.value
+ for child_node in node.targets:
+ ast.walk(child_node, self)
+
+ def _assigned(self, name, assignment=None):
+ self.scope_visitor._assigned(name, assignment)
+
+ def _Name(self, node):
+ assignment = None
+ if self.assigned_ast is not None:
+ assignment = pynames.AssignmentValue(self.assigned_ast)
+ self._assigned(node.id, assignment)
+
+ def _Tuple(self, node):
+ names = astutils.get_name_levels(node)
+ for name, levels in names:
+ assignment = None
+ if self.assigned_ast is not None:
+ assignment = pynames.AssignmentValue(self.assigned_ast, levels)
+ self._assigned(name, assignment)
+
+ def _Attribute(self, node):
+ pass
+
+ def _Subscript(self, node):
+ pass
+
+ def _Slice(self, node):
+ pass
+
+
+class _ScopeVisitor(object):
+
+ def __init__(self, pycore, owner_object):
+ self.pycore = pycore
+ self.owner_object = owner_object
+ self.names = {}
+ self.defineds = []
+
+ def get_module(self):
+ if self.owner_object is not None:
+ return self.owner_object.get_module()
+ else:
+ return None
+
+ def _ClassDef(self, node):
+ pyclass = PyClass(self.pycore, node, self.owner_object)
+ self.names[node.name] = pynames.DefinedName(pyclass)
+ self.defineds.append(pyclass)
+
+ def _FunctionDef(self, node):
+ pyfunction = PyFunction(self.pycore, node, self.owner_object)
+ for decorator in pyfunction.decorators:
+ if isinstance(decorator, ast.Name) and decorator.id == 'property':
+ if isinstance(self, _ClassVisitor):
+ type_ = rope.base.builtins.Property(pyfunction)
+ arg = pynames.UnboundName(
+ rope.base.pyobjects.PyObject(self.owner_object))
+
+ def _eval(type_=type_, arg=arg):
+ return type_.get_property_object(
+ arguments.ObjectArguments([arg]))
+ self.names[node.name] = pynames.EvaluatedName(
+ _eval, module=self.get_module(), lineno=node.lineno)
+ break
+ else:
+ self.names[node.name] = pynames.DefinedName(pyfunction)
+ self.defineds.append(pyfunction)
+
+ def _Assign(self, node):
+ ast.walk(node, _AssignVisitor(self))
+
+ def _AugAssign(self, node):
+ pass
+
+ def _For(self, node):
+ names = self._update_evaluated(node.target, node.iter, # noqa
+ '.__iter__().next()')
+ for child in node.body + node.orelse:
+ ast.walk(child, self)
+
+ def _assigned(self, name, assignment):
+ pyname = self.names.get(name, None)
+ if pyname is None:
+ pyname = pynames.AssignedName(module=self.get_module())
+ if isinstance(pyname, pynames.AssignedName):
+ if assignment is not None:
+ pyname.assignments.append(assignment)
+ self.names[name] = pyname
+
+ def _update_evaluated(self, targets, assigned,
+ evaluation='', eval_type=False):
+ result = {}
+ names = astutils.get_name_levels(targets)
+ for name, levels in names:
+ assignment = pynames.AssignmentValue(assigned, levels,
+ evaluation, eval_type)
+ self._assigned(name, assignment)
+ return result
+
+ def _With(self, node):
+ if node.optional_vars:
+ self._update_evaluated(node.optional_vars,
+ node.context_expr, '.__enter__()')
+ for child in node.body:
+ ast.walk(child, self)
+
+ def _excepthandler(self, node):
+ if node.name is not None and isinstance(node.name, ast.Name):
+ type_node = node.type
+ if isinstance(node.type, ast.Tuple) and type_node.elts:
+ type_node = type_node.elts[0]
+ self._update_evaluated(node.name, type_node, eval_type=True)
+ for child in node.body:
+ ast.walk(child, self)
+
+ def _ExceptHandler(self, node):
+ self._excepthandler(node)
+
+ def _Import(self, node):
+ for import_pair in node.names:
+ module_name = import_pair.name
+ alias = import_pair.asname
+ first_package = module_name.split('.')[0]
+ if alias is not None:
+ imported = pynames.ImportedModule(self.get_module(),
+ module_name)
+ if not self._is_ignored_import(imported):
+ self.names[alias] = imported
+ else:
+ imported = pynames.ImportedModule(self.get_module(),
+ first_package)
+ if not self._is_ignored_import(imported):
+ self.names[first_package] = imported
+
+ def _ImportFrom(self, node):
+ level = 0
+ if node.level:
+ level = node.level
+ imported_module = pynames.ImportedModule(self.get_module(),
+ node.module, level)
+ if self._is_ignored_import(imported_module):
+ return
+ if len(node.names) == 1 and node.names[0].name == '*':
+ if isinstance(self.owner_object, PyModule):
+ self.owner_object.star_imports.append(
+ StarImport(imported_module))
+ else:
+ for imported_name in node.names:
+ imported = imported_name.name
+ alias = imported_name.asname
+ if alias is not None:
+ imported = alias
+ self.names[imported] = pynames.ImportedName(imported_module,
+ imported_name.name)
+
+ def _is_ignored_import(self, imported_module):
+ if not self.pycore.project.prefs.get('ignore_bad_imports', False):
+ return False
+ return not isinstance(imported_module.get_object(),
+ rope.base.pyobjects.AbstractModule)
+
+ def _Global(self, node):
+ module = self.get_module()
+ for name in node.names:
+ if module is not None:
+ try:
+ pyname = module[name]
+ except exceptions.AttributeNotFoundError:
+ pyname = pynames.AssignedName(node.lineno)
+ self.names[name] = pyname
+
+
+class _GlobalVisitor(_ScopeVisitor):
+
+ def __init__(self, pycore, owner_object):
+ super(_GlobalVisitor, self).__init__(pycore, owner_object)
+
+
+class _ClassVisitor(_ScopeVisitor):
+
+ def __init__(self, pycore, owner_object):
+ super(_ClassVisitor, self).__init__(pycore, owner_object)
+
+ def _FunctionDef(self, node):
+ _ScopeVisitor._FunctionDef(self, node)
+ if len(node.args.args) > 0:
+ first = node.args.args[0]
+ if isinstance(first, ast.Name):
+ new_visitor = _ClassInitVisitor(self, first.id)
+ for child in ast.get_child_nodes(node):
+ ast.walk(child, new_visitor)
+
+
+class _FunctionVisitor(_ScopeVisitor):
+
+ def __init__(self, pycore, owner_object):
+ super(_FunctionVisitor, self).__init__(pycore, owner_object)
+ self.returned_asts = []
+ self.generator = False
+
+ def _Return(self, node):
+ if node.value is not None:
+ self.returned_asts.append(node.value)
+
+ def _Yield(self, node):
+ if node.value is not None:
+ self.returned_asts.append(node.value)
+ self.generator = True
+
+
+class _ClassInitVisitor(_AssignVisitor):
+
+ def __init__(self, scope_visitor, self_name):
+ super(_ClassInitVisitor, self).__init__(scope_visitor)
+ self.self_name = self_name
+
+ def _Attribute(self, node):
+ if not isinstance(node.ctx, ast.Store):
+ return
+ if isinstance(node.value, ast.Name) and \
+ node.value.id == self.self_name:
+ if node.attr not in self.scope_visitor.names:
+ self.scope_visitor.names[node.attr] = pynames.AssignedName(
+ lineno=node.lineno, module=self.scope_visitor.get_module())
+ if self.assigned_ast is not None:
+ pyname = self.scope_visitor.names[node.attr]
+ if isinstance(pyname, pynames.AssignedName):
+ pyname.assignments.append(
+ pynames.AssignmentValue(self.assigned_ast))
+
+ def _Tuple(self, node):
+ if not isinstance(node.ctx, ast.Store):
+ return
+ for child in ast.get_child_nodes(node):
+ ast.walk(child, self)
+
+ def _Name(self, node):
+ pass
+
+ def _FunctionDef(self, node):
+ pass
+
+ def _ClassDef(self, node):
+ pass
+
+ def _For(self, node):
+ pass
+
+ def _With(self, node):
+ pass
+
+
+class StarImport(object):
+
+ def __init__(self, imported_module):
+ self.imported_module = imported_module
+
+ def get_names(self):
+ result = {}
+ imported = self.imported_module.get_object()
+ for name in imported:
+ if not name.startswith('_'):
+ result[name] = pynames.ImportedName(self.imported_module, name)
+ return result
« no previous file with comments | « tools/telemetry/third_party/rope/rope/base/pyobjects.py ('k') | tools/telemetry/third_party/rope/rope/base/pyscopes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698