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

Unified Diff: tools/telemetry/third_party/rope/rope/refactor/introduce_parameter.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/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)

Powered by Google App Engine
This is Rietveld 408576698