| 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)
|
|
|