| Index: tools/telemetry/third_party/rope/rope/refactor/introduce_parameter.py
|
| diff --git a/tools/telemetry/third_party/rope/rope/refactor/introduce_parameter.py b/tools/telemetry/third_party/rope/rope/refactor/introduce_parameter.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..43d6f755b1170bf720e0a5d4558a1810278f29cd
|
| --- /dev/null
|
| +++ b/tools/telemetry/third_party/rope/rope/refactor/introduce_parameter.py
|
| @@ -0,0 +1,96 @@
|
| +import rope.base.change
|
| +from rope.base import exceptions, evaluate, worder, codeanalyze
|
| +from rope.refactor import functionutils, sourceutils, occurrences
|
| +
|
| +
|
| +class IntroduceParameter(object):
|
| + """Introduce parameter refactoring
|
| +
|
| + This refactoring adds a new parameter to a function and replaces
|
| + references to an expression in it with the new parameter.
|
| +
|
| + The parameter finding part is different from finding similar
|
| + pieces in extract refactorings. In this refactoring parameters
|
| + are found based on the object they reference to. For instance
|
| + in::
|
| +
|
| + class A(object):
|
| + var = None
|
| +
|
| + class B(object):
|
| + a = A()
|
| +
|
| + b = B()
|
| + a = b.a
|
| +
|
| + def f(a):
|
| + x = b.a.var + a.var
|
| +
|
| + using this refactoring on ``a.var`` with ``p`` as the new
|
| + parameter name, will result in::
|
| +
|
| + def f(p=a.var):
|
| + x = p + p
|
| +
|
| + """
|
| +
|
| + def __init__(self, project, resource, offset):
|
| + self.project = project
|
| + self.resource = resource
|
| + self.offset = offset
|
| + self.pymodule = self.project.get_pymodule(self.resource)
|
| + scope = self.pymodule.get_scope().get_inner_scope_for_offset(offset)
|
| + if scope.get_kind() != 'Function':
|
| + raise exceptions.RefactoringError(
|
| + 'Introduce parameter should be performed inside functions')
|
| + self.pyfunction = scope.pyobject
|
| + self.name, self.pyname = self._get_name_and_pyname()
|
| + if self.pyname is None:
|
| + raise exceptions.RefactoringError(
|
| + 'Cannot find the definition of <%s>' % self.name)
|
| +
|
| + def _get_primary(self):
|
| + word_finder = worder.Worder(self.resource.read())
|
| + return word_finder.get_primary_at(self.offset)
|
| +
|
| + def _get_name_and_pyname(self):
|
| + return (worder.get_name_at(self.resource, self.offset),
|
| + evaluate.eval_location(self.pymodule, self.offset))
|
| +
|
| + def get_changes(self, new_parameter):
|
| + definition_info = functionutils.DefinitionInfo.read(self.pyfunction)
|
| + definition_info.args_with_defaults.append((new_parameter,
|
| + self._get_primary()))
|
| + collector = codeanalyze.ChangeCollector(self.resource.read())
|
| + header_start, header_end = self._get_header_offsets()
|
| + body_start, body_end = sourceutils.get_body_region(self.pyfunction)
|
| + collector.add_change(header_start, header_end,
|
| + definition_info.to_string())
|
| + self._change_function_occurances(collector, body_start,
|
| + body_end, new_parameter)
|
| + changes = rope.base.change.ChangeSet('Introduce parameter <%s>' %
|
| + new_parameter)
|
| + change = rope.base.change.ChangeContents(self.resource,
|
| + collector.get_changed())
|
| + changes.add_change(change)
|
| + return changes
|
| +
|
| + def _get_header_offsets(self):
|
| + lines = self.pymodule.lines
|
| + start_line = self.pyfunction.get_scope().get_start()
|
| + end_line = self.pymodule.logical_lines.\
|
| + logical_line_in(start_line)[1]
|
| + start = lines.get_line_start(start_line)
|
| + end = lines.get_line_end(end_line)
|
| + start = self.pymodule.source_code.find('def', start) + 4
|
| + end = self.pymodule.source_code.rfind(':', start, end)
|
| + return start, end
|
| +
|
| + def _change_function_occurances(self, collector, function_start,
|
| + function_end, new_name):
|
| + finder = occurrences.create_finder(self.project, self.name,
|
| + self.pyname)
|
| + for occurrence in finder.find_occurrences(resource=self.resource):
|
| + start, end = occurrence.get_primary_range()
|
| + if function_start <= start < function_end:
|
| + collector.add_change(start, end, new_name)
|
|
|