def usages(self, additional_module_paths=()): """ Return :class:`api_classes.Usage` objects, which contain all names that point to the definition of the name under the cursor. This is very useful for refactoring (renaming), or to show all usages of a variable. .. todo:: Implement additional_module_paths :rtype: list of :class:`api_classes.Usage` """ temp, settings.dynamic_flow_information = \ settings.dynamic_flow_information, False user_stmt = self._user_stmt() definitions, search_name = self._goto(add_import_name=True) if isinstance(user_stmt, pr.Statement): c = user_stmt.get_commands()[0] if not isinstance(c, unicode) and self._pos < c.start_pos: # the search_name might be before `=` definitions = [ v for v in user_stmt.get_set_vars() if unicode(v.names[-1]) == search_name ] if not isinstance(user_stmt, pr.Import): # import case is looked at with add_import_name option definitions = dynamic.usages_add_import_modules( definitions, search_name) module = set([d.get_parent_until() for d in definitions]) module.add(self._parser.module) names = dynamic.usages(definitions, search_name, module) for d in set(definitions): if isinstance(d, pr.Module): names.append(api_classes.Usage(d, d)) elif isinstance(d, er.Instance): # Instances can be ignored, because they are being created by # ``__getattr__``. pass else: names.append(api_classes.Usage(d.names[-1], d)) settings.dynamic_flow_information = temp return self._sorted_defs(set(names))
def usages(self, additional_module_paths=()): """ Return :class:`api_classes.Usage` objects, which contain all names that point to the definition of the name under the cursor. This is very useful for refactoring (renaming), or to show all usages of a variable. .. todo:: Implement additional_module_paths :rtype: list of :class:`api_classes.Usage` """ user_stmt = self._parser.user_stmt definitions, search_name = self._goto(add_import_name=True) if isinstance(user_stmt, pr.Statement) \ and self.pos < user_stmt.get_commands()[0].start_pos: # the search_name might be before `=` definitions = [ v for v in user_stmt.set_vars if unicode(v.names[-1]) == search_name ] if not isinstance(user_stmt, pr.Import): # import case is looked at with add_import_name option definitions = dynamic.usages_add_import_modules( definitions, search_name) module = set([d.get_parent_until() for d in definitions]) module.add(self._parser.module) names = dynamic.usages(definitions, search_name, module) for d in set(definitions): if isinstance(d, pr.Module): names.append(api_classes.Usage(d, d)) else: names.append(api_classes.Usage(d.names[-1], d)) return self._sorted_defs(set(names))
def check_call(call): result = [] follow = [] # There might be multiple search_name's in one call_path call_path = list(call.generate_call_path()) for i, name in enumerate(call_path): # name is `pr.NamePart`. if name == search_name: follow.append(call_path[:i + 1]) for f in follow: follow_res, search = evaluate.goto(call.parent, f) follow_res = usages_add_import_modules(follow_res, search) compare_follow_res = compare_array(follow_res) # compare to see if they match if any(r in compare_definitions for r in compare_follow_res): scope = call.parent result.append(api_classes.Usage(search, scope)) return result
def usages(definitions, search_name, mods): def compare_array(definitions): """ `definitions` are being compared by module/start_pos, because sometimes the id's of the objects change (e.g. executions). """ result = [] for d in definitions: module = d.get_parent_until() result.append((module, d.start_pos)) return result def check_call(call): result = [] follow = [] # There might be multiple search_name's in one call_path call_path = list(call.generate_call_path()) for i, name in enumerate(call_path): # name is `pr.NamePart`. if name == search_name: follow.append(call_path[:i + 1]) for f in follow: follow_res, search = evaluate.goto(call.parent, f) follow_res = usages_add_import_modules(follow_res, search) compare_follow_res = compare_array(follow_res) # compare to see if they match if any(r in compare_definitions for r in compare_follow_res): scope = call.parent result.append(api_classes.Usage(search, scope)) return result if not definitions: return set() compare_definitions = compare_array(definitions) mods |= set([d.get_parent_until() for d in definitions]) names = [] for m in get_directory_modules_for_name(mods, search_name): try: stmts = m.used_names[search_name] except KeyError: continue for stmt in stmts: if isinstance(stmt, pr.Import): count = 0 imps = [] for i in stmt.get_all_import_names(): for name_part in i.names: count += 1 if name_part == search_name: imps.append((count, name_part)) for used_count, name_part in imps: i = imports.ImportPath(stmt, kill_count=count - used_count, direct_resolve=True) f = i.follow(is_goto=True) if set(f) & set(definitions): names.append(api_classes.Usage(name_part, stmt)) else: for call in _scan_statement(stmt, search_name, assignment_details=True): names += check_call(call) return names