Index: tools/telemetry/third_party/rope/rope/base/oi/transform.py |
diff --git a/tools/telemetry/third_party/rope/rope/base/oi/transform.py b/tools/telemetry/third_party/rope/rope/base/oi/transform.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..aa29c373d5cb34e24994ed2e43c86f0a080276a0 |
--- /dev/null |
+++ b/tools/telemetry/third_party/rope/rope/base/oi/transform.py |
@@ -0,0 +1,285 @@ |
+"""Provides classes for persisting `PyObject`\s""" |
+import os |
+import re |
+ |
+import rope.base.builtins |
+from rope.base import exceptions |
+ |
+ |
+class PyObjectToTextual(object): |
+ """For transforming `PyObject` to textual form |
+ |
+ This can be used for storing `PyObjects` in files. Use |
+ `TextualToPyObject` for converting back. |
+ |
+ """ |
+ |
+ def __init__(self, project): |
+ self.project = project |
+ |
+ def transform(self, pyobject): |
+ """Transform a `PyObject` to textual form""" |
+ if pyobject is None: |
+ return ('none',) |
+ object_type = type(pyobject) |
+ try: |
+ method = getattr(self, object_type.__name__ + '_to_textual') |
+ return method(pyobject) |
+ except AttributeError: |
+ return ('unknown',) |
+ |
+ def __call__(self, pyobject): |
+ return self.transform(pyobject) |
+ |
+ def PyObject_to_textual(self, pyobject): |
+ if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass): |
+ result = self.transform(pyobject.get_type()) |
+ if result[0] == 'defined': |
+ return ('instance', result) |
+ return result |
+ return ('unknown',) |
+ |
+ def PyFunction_to_textual(self, pyobject): |
+ return self._defined_to_textual(pyobject) |
+ |
+ def PyClass_to_textual(self, pyobject): |
+ return self._defined_to_textual(pyobject) |
+ |
+ def _defined_to_textual(self, pyobject): |
+ address = [] |
+ while pyobject.parent is not None: |
+ address.insert(0, pyobject.get_name()) |
+ pyobject = pyobject.parent |
+ return ('defined', self._get_pymodule_path(pyobject.get_module()), |
+ '.'.join(address)) |
+ |
+ def PyModule_to_textual(self, pyobject): |
+ return ('defined', self._get_pymodule_path(pyobject)) |
+ |
+ def PyPackage_to_textual(self, pyobject): |
+ return ('defined', self._get_pymodule_path(pyobject)) |
+ |
+ def List_to_textual(self, pyobject): |
+ return ('builtin', 'list', self.transform(pyobject.holding)) |
+ |
+ def Dict_to_textual(self, pyobject): |
+ return ('builtin', 'dict', self.transform(pyobject.keys), |
+ self.transform(pyobject.values)) |
+ |
+ def Tuple_to_textual(self, pyobject): |
+ objects = [self.transform(holding) |
+ for holding in pyobject.get_holding_objects()] |
+ return tuple(['builtin', 'tuple'] + objects) |
+ |
+ def Set_to_textual(self, pyobject): |
+ return ('builtin', 'set', self.transform(pyobject.holding)) |
+ |
+ def Iterator_to_textual(self, pyobject): |
+ return ('builtin', 'iter', self.transform(pyobject.holding)) |
+ |
+ def Generator_to_textual(self, pyobject): |
+ return ('builtin', 'generator', self.transform(pyobject.holding)) |
+ |
+ def Str_to_textual(self, pyobject): |
+ return ('builtin', 'str') |
+ |
+ def File_to_textual(self, pyobject): |
+ return ('builtin', 'file') |
+ |
+ def BuiltinFunction_to_textual(self, pyobject): |
+ return ('builtin', 'function', pyobject.get_name()) |
+ |
+ def _get_pymodule_path(self, pymodule): |
+ return self.resource_to_path(pymodule.get_resource()) |
+ |
+ def resource_to_path(self, resource): |
+ if resource.project == self.project: |
+ return resource.path |
+ else: |
+ return resource.real_path |
+ |
+ |
+class TextualToPyObject(object): |
+ """For transforming textual form to `PyObject`""" |
+ |
+ def __init__(self, project, allow_in_project_absolutes=False): |
+ self.project = project |
+ |
+ def __call__(self, textual): |
+ return self.transform(textual) |
+ |
+ def transform(self, textual): |
+ """Transform an object from textual form to `PyObject`""" |
+ if textual is None: |
+ return None |
+ type = textual[0] |
+ try: |
+ method = getattr(self, type + '_to_pyobject') |
+ return method(textual) |
+ except AttributeError: |
+ return None |
+ |
+ def builtin_to_pyobject(self, textual): |
+ method = getattr(self, 'builtin_%s_to_pyobject' % textual[1], None) |
+ if method is not None: |
+ return method(textual) |
+ |
+ def builtin_str_to_pyobject(self, textual): |
+ return rope.base.builtins.get_str() |
+ |
+ def builtin_list_to_pyobject(self, textual): |
+ holding = self.transform(textual[2]) |
+ return rope.base.builtins.get_list(holding) |
+ |
+ def builtin_dict_to_pyobject(self, textual): |
+ keys = self.transform(textual[2]) |
+ values = self.transform(textual[3]) |
+ return rope.base.builtins.get_dict(keys, values) |
+ |
+ def builtin_tuple_to_pyobject(self, textual): |
+ objects = [] |
+ for holding in textual[2:]: |
+ objects.append(self.transform(holding)) |
+ return rope.base.builtins.get_tuple(*objects) |
+ |
+ def builtin_set_to_pyobject(self, textual): |
+ holding = self.transform(textual[2]) |
+ return rope.base.builtins.get_set(holding) |
+ |
+ def builtin_iter_to_pyobject(self, textual): |
+ holding = self.transform(textual[2]) |
+ return rope.base.builtins.get_iterator(holding) |
+ |
+ def builtin_generator_to_pyobject(self, textual): |
+ holding = self.transform(textual[2]) |
+ return rope.base.builtins.get_generator(holding) |
+ |
+ def builtin_file_to_pyobject(self, textual): |
+ return rope.base.builtins.get_file() |
+ |
+ def builtin_function_to_pyobject(self, textual): |
+ if textual[2] in rope.base.builtins.builtins: |
+ return rope.base.builtins.builtins[textual[2]].get_object() |
+ |
+ def unknown_to_pyobject(self, textual): |
+ return None |
+ |
+ def none_to_pyobject(self, textual): |
+ return None |
+ |
+ def _module_to_pyobject(self, textual): |
+ path = textual[1] |
+ return self._get_pymodule(path) |
+ |
+ def _hierarchical_defined_to_pyobject(self, textual): |
+ path = textual[1] |
+ names = textual[2].split('.') |
+ pymodule = self._get_pymodule(path) |
+ pyobject = pymodule |
+ for name in names: |
+ if pyobject is None: |
+ return None |
+ if isinstance(pyobject, rope.base.pyobjects.PyDefinedObject): |
+ try: |
+ pyobject = pyobject.get_scope()[name].get_object() |
+ except exceptions.NameNotFoundError: |
+ return None |
+ else: |
+ return None |
+ return pyobject |
+ |
+ def defined_to_pyobject(self, textual): |
+ if len(textual) == 2 or textual[2] == '': |
+ return self._module_to_pyobject(textual) |
+ else: |
+ return self._hierarchical_defined_to_pyobject(textual) |
+ |
+ def instance_to_pyobject(self, textual): |
+ type = self.transform(textual[1]) |
+ if type is not None: |
+ return rope.base.pyobjects.PyObject(type) |
+ |
+ def _get_pymodule(self, path): |
+ resource = self.path_to_resource(path) |
+ if resource is not None: |
+ return self.project.get_pymodule(resource) |
+ |
+ def path_to_resource(self, path): |
+ try: |
+ root = self.project.address |
+ if not os.path.isabs(path): |
+ return self.project.get_resource(path) |
+ if path == root or path.startswith(root + os.sep): |
+ # INFO: This is a project file; should not be absolute |
+ return None |
+ import rope.base.project |
+ return rope.base.project.get_no_project().get_resource(path) |
+ except exceptions.ResourceNotFoundError: |
+ return None |
+ |
+ |
+class DOITextualToPyObject(TextualToPyObject): |
+ """For transforming textual form to `PyObject` |
+ |
+ The textual form DOI uses is different from rope's standard |
+ textual form. The reason is that we cannot find the needed |
+ information by analyzing live objects. This class can be |
+ used to transform DOI textual form to `PyObject` and later |
+ we can convert it to standard textual form using |
+ `TextualToPyObject` class. |
+ |
+ """ |
+ |
+ def _function_to_pyobject(self, textual): |
+ path = textual[1] |
+ lineno = int(textual[2]) |
+ pymodule = self._get_pymodule(path) |
+ if pymodule is not None: |
+ scope = pymodule.get_scope() |
+ inner_scope = scope.get_inner_scope_for_line(lineno) |
+ return inner_scope.pyobject |
+ |
+ def _class_to_pyobject(self, textual): |
+ path, name = textual[1:] |
+ pymodule = self._get_pymodule(path) |
+ if pymodule is None: |
+ return None |
+ module_scope = pymodule.get_scope() |
+ suspected = None |
+ if name in module_scope.get_names(): |
+ suspected = module_scope[name].get_object() |
+ if suspected is not None and \ |
+ isinstance(suspected, rope.base.pyobjects.PyClass): |
+ return suspected |
+ else: |
+ lineno = self._find_occurrence(name, |
+ pymodule.get_resource().read()) |
+ if lineno is not None: |
+ inner_scope = module_scope.get_inner_scope_for_line(lineno) |
+ return inner_scope.pyobject |
+ |
+ def defined_to_pyobject(self, textual): |
+ if len(textual) == 2: |
+ return self._module_to_pyobject(textual) |
+ else: |
+ if textual[2].isdigit(): |
+ result = self._function_to_pyobject(textual) |
+ else: |
+ result = self._class_to_pyobject(textual) |
+ if not isinstance(result, rope.base.pyobjects.PyModule): |
+ return result |
+ |
+ def _find_occurrence(self, name, source): |
+ pattern = re.compile(r'^\s*class\s*' + name + r'\b') |
+ lines = source.split('\n') |
+ for i in range(len(lines)): |
+ if pattern.match(lines[i]): |
+ return i + 1 |
+ |
+ def path_to_resource(self, path): |
+ import rope.base.libutils |
+ relpath = rope.base.libutils.path_relative_to_project_root( |
+ self.project, path) |
+ if relpath is not None: |
+ path = relpath |
+ return super(DOITextualToPyObject, self).path_to_resource(path) |