Index: tools/telemetry/third_party/rope/rope/refactor/suites.py |
diff --git a/tools/telemetry/third_party/rope/rope/refactor/suites.py b/tools/telemetry/third_party/rope/rope/refactor/suites.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4f9a8c715c9986f1a3a296c2cf50dd721f246d40 |
--- /dev/null |
+++ b/tools/telemetry/third_party/rope/rope/refactor/suites.py |
@@ -0,0 +1,143 @@ |
+from rope.base import ast |
+ |
+ |
+def find_visible(node, lines): |
+ """Return the line which is visible from all `lines`""" |
+ root = ast_suite_tree(node) |
+ return find_visible_for_suite(root, lines) |
+ |
+ |
+def find_visible_for_suite(root, lines): |
+ if len(lines) == 1: |
+ return lines[0] |
+ line1 = lines[0] |
+ line2 = find_visible_for_suite(root, lines[1:]) |
+ suite1 = root.find_suite(line1) |
+ suite2 = root.find_suite(line2) |
+ |
+ def valid(suite): |
+ return suite is not None and not suite.ignored |
+ if valid(suite1) and not valid(suite2): |
+ return line1 |
+ if not valid(suite1) and valid(suite2): |
+ return line2 |
+ if not valid(suite1) and not valid(suite2): |
+ return None |
+ while suite1 != suite2 and suite1.parent != suite2.parent: |
+ if suite1._get_level() < suite2._get_level(): |
+ line2 = suite2.get_start() |
+ suite2 = suite2.parent |
+ elif suite1._get_level() > suite2._get_level(): |
+ line1 = suite1.get_start() |
+ suite1 = suite1.parent |
+ else: |
+ line1 = suite1.get_start() |
+ line2 = suite2.get_start() |
+ suite1 = suite1.parent |
+ suite2 = suite2.parent |
+ if suite1 == suite2: |
+ return min(line1, line2) |
+ return min(suite1.get_start(), suite2.get_start()) |
+ |
+ |
+def ast_suite_tree(node): |
+ if hasattr(node, 'lineno'): |
+ lineno = node.lineno |
+ else: |
+ lineno = 1 |
+ return Suite(node.body, lineno) |
+ |
+ |
+class Suite(object): |
+ |
+ def __init__(self, child_nodes, lineno, parent=None, ignored=False): |
+ self.parent = parent |
+ self.lineno = lineno |
+ self.child_nodes = child_nodes |
+ self._children = None |
+ self.ignored = ignored |
+ |
+ def get_start(self): |
+ if self.parent is None: |
+ if self.child_nodes: |
+ return self.local_start() |
+ else: |
+ return 1 |
+ return self.lineno |
+ |
+ def get_children(self): |
+ if self._children is None: |
+ walker = _SuiteWalker(self) |
+ for child in self.child_nodes: |
+ ast.walk(child, walker) |
+ self._children = walker.suites |
+ return self._children |
+ |
+ def local_start(self): |
+ return self.child_nodes[0].lineno |
+ |
+ def local_end(self): |
+ end = self.child_nodes[-1].lineno |
+ if self.get_children(): |
+ end = max(end, self.get_children()[-1].local_end()) |
+ return end |
+ |
+ def find_suite(self, line): |
+ if line is None: |
+ return None |
+ for child in self.get_children(): |
+ if child.local_start() <= line <= child.local_end(): |
+ return child.find_suite(line) |
+ return self |
+ |
+ def _get_level(self): |
+ if self.parent is None: |
+ return 0 |
+ return self.parent._get_level() + 1 |
+ |
+ |
+class _SuiteWalker(object): |
+ |
+ def __init__(self, suite): |
+ self.suite = suite |
+ self.suites = [] |
+ |
+ def _If(self, node): |
+ self._add_if_like_node(node) |
+ |
+ def _For(self, node): |
+ self._add_if_like_node(node) |
+ |
+ def _While(self, node): |
+ self._add_if_like_node(node) |
+ |
+ def _With(self, node): |
+ self.suites.append(Suite(node.body, node.lineno, self.suite)) |
+ |
+ def _TryFinally(self, node): |
+ if len(node.finalbody) == 1 and \ |
+ isinstance(node.body[0], ast.TryExcept): |
+ self._TryExcept(node.body[0]) |
+ else: |
+ self.suites.append(Suite(node.body, node.lineno, self.suite)) |
+ self.suites.append(Suite(node.finalbody, node.lineno, self.suite)) |
+ |
+ def _TryExcept(self, node): |
+ self.suites.append(Suite(node.body, node.lineno, self.suite)) |
+ for handler in node.handlers: |
+ self.suites.append(Suite(handler.body, node.lineno, self.suite)) |
+ if node.orelse: |
+ self.suites.append(Suite(node.orelse, node.lineno, self.suite)) |
+ |
+ def _add_if_like_node(self, node): |
+ self.suites.append(Suite(node.body, node.lineno, self.suite)) |
+ if node.orelse: |
+ self.suites.append(Suite(node.orelse, node.lineno, self.suite)) |
+ |
+ def _FunctionDef(self, node): |
+ self.suites.append(Suite(node.body, node.lineno, |
+ self.suite, ignored=True)) |
+ |
+ def _ClassDef(self, node): |
+ self.suites.append(Suite(node.body, node.lineno, |
+ self.suite, ignored=True)) |