| Index: tools/telemetry/third_party/rope/rope/refactor/method_object.py
|
| diff --git a/tools/telemetry/third_party/rope/rope/refactor/method_object.py b/tools/telemetry/third_party/rope/rope/refactor/method_object.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..29ce429db6115a389cda2b8adf6b7e0d194324f0
|
| --- /dev/null
|
| +++ b/tools/telemetry/third_party/rope/rope/refactor/method_object.py
|
| @@ -0,0 +1,90 @@
|
| +import warnings
|
| +
|
| +from rope.base import libutils
|
| +from rope.base import pyobjects, exceptions, change, evaluate, codeanalyze
|
| +from rope.refactor import sourceutils, occurrences, rename
|
| +
|
| +
|
| +class MethodObject(object):
|
| +
|
| + def __init__(self, project, resource, offset):
|
| + self.project = project
|
| + this_pymodule = self.project.get_pymodule(resource)
|
| + pyname = evaluate.eval_location(this_pymodule, offset)
|
| + if pyname is None or not isinstance(pyname.get_object(),
|
| + pyobjects.PyFunction):
|
| + raise exceptions.RefactoringError(
|
| + 'Replace method with method object refactoring should be '
|
| + 'performed on a function.')
|
| + self.pyfunction = pyname.get_object()
|
| + self.pymodule = self.pyfunction.get_module()
|
| + self.resource = self.pymodule.get_resource()
|
| +
|
| + def get_new_class(self, name):
|
| + body = sourceutils.fix_indentation(
|
| + self._get_body(), sourceutils.get_indent(self.project) * 2)
|
| + return 'class %s(object):\n\n%s%sdef __call__(self):\n%s' % \
|
| + (name, self._get_init(),
|
| + ' ' * sourceutils.get_indent(self.project), body)
|
| +
|
| + def get_changes(self, classname=None, new_class_name=None):
|
| + if new_class_name is not None:
|
| + warnings.warn(
|
| + 'new_class_name parameter is deprecated; use classname',
|
| + DeprecationWarning, stacklevel=2)
|
| + classname = new_class_name
|
| + collector = codeanalyze.ChangeCollector(self.pymodule.source_code)
|
| + start, end = sourceutils.get_body_region(self.pyfunction)
|
| + indents = sourceutils.get_indents(
|
| + self.pymodule.lines, self.pyfunction.get_scope().get_start()) + \
|
| + sourceutils.get_indent(self.project)
|
| + new_contents = ' ' * indents + 'return %s(%s)()\n' % \
|
| + (classname, ', '.join(self._get_parameter_names()))
|
| + collector.add_change(start, end, new_contents)
|
| + insertion = self._get_class_insertion_point()
|
| + collector.add_change(insertion, insertion,
|
| + '\n\n' + self.get_new_class(classname))
|
| + changes = change.ChangeSet(
|
| + 'Replace method with method object refactoring')
|
| + changes.add_change(change.ChangeContents(self.resource,
|
| + collector.get_changed()))
|
| + return changes
|
| +
|
| + def _get_class_insertion_point(self):
|
| + current = self.pyfunction
|
| + while current.parent != self.pymodule:
|
| + current = current.parent
|
| + end = self.pymodule.lines.get_line_end(current.get_scope().get_end())
|
| + return min(end + 1, len(self.pymodule.source_code))
|
| +
|
| + def _get_body(self):
|
| + body = sourceutils.get_body(self.pyfunction)
|
| + for param in self._get_parameter_names():
|
| + body = param + ' = None\n' + body
|
| + pymod = libutils.get_string_module(
|
| + self.project, body, self.resource)
|
| + pyname = pymod[param]
|
| + finder = occurrences.create_finder(self.project, param, pyname)
|
| + result = rename.rename_in_module(finder, 'self.' + param,
|
| + pymodule=pymod)
|
| + body = result[result.index('\n') + 1:]
|
| + return body
|
| +
|
| + def _get_init(self):
|
| + params = self._get_parameter_names()
|
| + indents = ' ' * sourceutils.get_indent(self.project)
|
| + if not params:
|
| + return ''
|
| + header = indents + 'def __init__(self'
|
| + body = ''
|
| + for arg in params:
|
| + new_name = arg
|
| + if arg == 'self':
|
| + new_name = 'host'
|
| + header += ', %s' % new_name
|
| + body += indents * 2 + 'self.%s = %s\n' % (arg, new_name)
|
| + header += '):'
|
| + return '%s\n%s\n' % (header, body)
|
| +
|
| + def _get_parameter_names(self):
|
| + return self.pyfunction.get_param_names()
|
|
|