| Index: tools/telemetry/third_party/rope/rope/base/oi/objectinfo.py
|
| diff --git a/tools/telemetry/third_party/rope/rope/base/oi/objectinfo.py b/tools/telemetry/third_party/rope/rope/base/oi/objectinfo.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f86d72e0b5cc26f2432aa678f7e5144451f5e8fa
|
| --- /dev/null
|
| +++ b/tools/telemetry/third_party/rope/rope/base/oi/objectinfo.py
|
| @@ -0,0 +1,232 @@
|
| +import warnings
|
| +
|
| +from rope.base import exceptions, resourceobserver
|
| +from rope.base.oi import objectdb, memorydb, transform
|
| +
|
| +
|
| +class ObjectInfoManager(object):
|
| + """Stores object information
|
| +
|
| + It uses an instance of `objectdb.ObjectDB` for storing
|
| + information.
|
| +
|
| + """
|
| +
|
| + def __init__(self, project):
|
| + self.project = project
|
| + self.to_textual = transform.PyObjectToTextual(project)
|
| + self.to_pyobject = transform.TextualToPyObject(project)
|
| + self.doi_to_pyobject = transform.DOITextualToPyObject(project)
|
| + self._init_objectdb()
|
| + if project.prefs.get('validate_objectdb', False):
|
| + self._init_validation()
|
| +
|
| + def _init_objectdb(self):
|
| + dbtype = self.project.get_prefs().get('objectdb_type', None)
|
| + persist = None
|
| + if dbtype is not None:
|
| + warnings.warn(
|
| + '"objectdb_type" project config is deprecated;\n'
|
| + 'Use "save_objectdb" instead in your project '
|
| + 'config file.\n(".ropeproject/config.py" by default)\n',
|
| + DeprecationWarning)
|
| + if dbtype != 'memory' and self.project.ropefolder is not None:
|
| + persist = True
|
| + self.validation = TextualValidation(self.to_pyobject)
|
| + db = memorydb.MemoryDB(self.project, persist=persist)
|
| + self.objectdb = objectdb.ObjectDB(db, self.validation)
|
| +
|
| + def _init_validation(self):
|
| + self.objectdb.validate_files()
|
| + observer = resourceobserver.ResourceObserver(
|
| + changed=self._resource_changed, moved=self._resource_moved,
|
| + removed=self._resource_moved)
|
| + files = []
|
| + for path in self.objectdb.get_files():
|
| + resource = self.to_pyobject.path_to_resource(path)
|
| + if resource is not None and resource.project == self.project:
|
| + files.append(resource)
|
| + self.observer = resourceobserver.FilteredResourceObserver(observer,
|
| + files)
|
| + self.objectdb.add_file_list_observer(_FileListObserver(self))
|
| + self.project.add_observer(self.observer)
|
| +
|
| + def _resource_changed(self, resource):
|
| + try:
|
| + self.objectdb.validate_file(
|
| + self.to_textual.resource_to_path(resource))
|
| + except exceptions.ModuleSyntaxError:
|
| + pass
|
| +
|
| + def _resource_moved(self, resource, new_resource=None):
|
| + self.observer.remove_resource(resource)
|
| + if new_resource is not None:
|
| + old = self.to_textual.resource_to_path(resource)
|
| + new = self.to_textual.resource_to_path(new_resource)
|
| + self.objectdb.file_moved(old, new)
|
| + self.observer.add_resource(new_resource)
|
| +
|
| + def get_returned(self, pyobject, args):
|
| + result = self.get_exact_returned(pyobject, args)
|
| + if result is not None:
|
| + return result
|
| + path, key = self._get_scope(pyobject)
|
| + if path is None:
|
| + return None
|
| + for call_info in self.objectdb.get_callinfos(path, key):
|
| + returned = call_info.get_returned()
|
| + if returned and returned[0] not in ('unknown', 'none'):
|
| + result = returned
|
| + break
|
| + if result is None:
|
| + result = returned
|
| + if result is not None:
|
| + return self.to_pyobject(result)
|
| +
|
| + def get_exact_returned(self, pyobject, args):
|
| + path, key = self._get_scope(pyobject)
|
| + if path is not None:
|
| + returned = self.objectdb.get_returned(
|
| + path, key, self._args_to_textual(pyobject, args))
|
| + if returned is not None:
|
| + return self.to_pyobject(returned)
|
| +
|
| + def _args_to_textual(self, pyfunction, args):
|
| + parameters = list(pyfunction.get_param_names(special_args=False))
|
| + arguments = args.get_arguments(parameters)[:len(parameters)]
|
| + textual_args = tuple([self.to_textual(arg)
|
| + for arg in arguments])
|
| + return textual_args
|
| +
|
| + def get_parameter_objects(self, pyobject):
|
| + path, key = self._get_scope(pyobject)
|
| + if path is None:
|
| + return None
|
| + arg_count = len(pyobject.get_param_names(special_args=False))
|
| + unknowns = arg_count
|
| + parameters = [None] * arg_count
|
| + for call_info in self.objectdb.get_callinfos(path, key):
|
| + args = call_info.get_parameters()
|
| + for index, arg in enumerate(args[:arg_count]):
|
| + old = parameters[index]
|
| + if self.validation.is_more_valid(arg, old):
|
| + parameters[index] = arg
|
| + if self.validation.is_value_valid(arg):
|
| + unknowns -= 1
|
| + if unknowns == 0:
|
| + break
|
| + if unknowns < arg_count:
|
| + return [self.to_pyobject(parameter)
|
| + for parameter in parameters]
|
| +
|
| + def get_passed_objects(self, pyfunction, parameter_index):
|
| + path, key = self._get_scope(pyfunction)
|
| + if path is None:
|
| + return []
|
| + result = []
|
| + for call_info in self.objectdb.get_callinfos(path, key):
|
| + args = call_info.get_parameters()
|
| + if len(args) > parameter_index:
|
| + parameter = self.to_pyobject(args[parameter_index])
|
| + if parameter is not None:
|
| + result.append(parameter)
|
| + return result
|
| +
|
| + def doa_data_received(self, data):
|
| + def doi_to_normal(textual):
|
| + pyobject = self.doi_to_pyobject(textual)
|
| + return self.to_textual(pyobject)
|
| + function = doi_to_normal(data[0])
|
| + args = tuple([doi_to_normal(textual) for textual in data[1]])
|
| + returned = doi_to_normal(data[2])
|
| + if function[0] == 'defined' and len(function) == 3:
|
| + self._save_data(function, args, returned)
|
| +
|
| + def function_called(self, pyfunction, params, returned=None):
|
| + function_text = self.to_textual(pyfunction)
|
| + params_text = tuple([self.to_textual(param)
|
| + for param in params])
|
| + returned_text = ('unknown',)
|
| + if returned is not None:
|
| + returned_text = self.to_textual(returned)
|
| + self._save_data(function_text, params_text, returned_text)
|
| +
|
| + def save_per_name(self, scope, name, data):
|
| + path, key = self._get_scope(scope.pyobject)
|
| + if path is not None:
|
| + self.objectdb.add_pername(path, key, name, self.to_textual(data))
|
| +
|
| + def get_per_name(self, scope, name):
|
| + path, key = self._get_scope(scope.pyobject)
|
| + if path is not None:
|
| + result = self.objectdb.get_pername(path, key, name)
|
| + if result is not None:
|
| + return self.to_pyobject(result)
|
| +
|
| + def _save_data(self, function, args, returned=('unknown',)):
|
| + self.objectdb.add_callinfo(function[1], function[2], args, returned)
|
| +
|
| + def _get_scope(self, pyobject):
|
| + resource = pyobject.get_module().get_resource()
|
| + if resource is None:
|
| + return None, None
|
| + textual = self.to_textual(pyobject)
|
| + if textual[0] == 'defined':
|
| + path = textual[1]
|
| + if len(textual) == 3:
|
| + key = textual[2]
|
| + else:
|
| + key = ''
|
| + return path, key
|
| + return None, None
|
| +
|
| + def sync(self):
|
| + self.objectdb.sync()
|
| +
|
| + def __str__(self):
|
| + return str(self.objectdb)
|
| +
|
| +
|
| +class TextualValidation(object):
|
| +
|
| + def __init__(self, to_pyobject):
|
| + self.to_pyobject = to_pyobject
|
| +
|
| + def is_value_valid(self, value):
|
| + # ???: Should none and unknown be considered valid?
|
| + if value is None or value[0] in ('none', 'unknown'):
|
| + return False
|
| + return self.to_pyobject(value) is not None
|
| +
|
| + def is_more_valid(self, new, old):
|
| + if old is None:
|
| + return True
|
| + return new[0] not in ('unknown', 'none')
|
| +
|
| + def is_file_valid(self, path):
|
| + return self.to_pyobject.path_to_resource(path) is not None
|
| +
|
| + def is_scope_valid(self, path, key):
|
| + if key == '':
|
| + textual = ('defined', path)
|
| + else:
|
| + textual = ('defined', path, key)
|
| + return self.to_pyobject(textual) is not None
|
| +
|
| +
|
| +class _FileListObserver(object):
|
| +
|
| + def __init__(self, object_info):
|
| + self.object_info = object_info
|
| + self.observer = self.object_info.observer
|
| + self.to_pyobject = self.object_info.to_pyobject
|
| +
|
| + def removed(self, path):
|
| + resource = self.to_pyobject.path_to_resource(path)
|
| + if resource is not None:
|
| + self.observer.remove_resource(resource)
|
| +
|
| + def added(self, path):
|
| + resource = self.to_pyobject.path_to_resource(path)
|
| + if resource is not None:
|
| + self.observer.add_resource(resource)
|
|
|