def defined_names(self): """ List sub-definitions (e.g., methods in class). :rtype: list of Definition """ defs = self._name.infer() return sorted(unite(defined_names(self._evaluator, d) for d in defs), key=lambda s: s._name.start_pos or (0, 0))
def infer_import(context, tree_name, is_goto=False): module_context = context.get_root_context() import_node = search_ancestor(tree_name, 'import_name', 'import_from') import_path = import_node.get_path_for_name(tree_name) from_import_name = None evaluator = context.evaluator try: from_names = import_node.get_from_names() except AttributeError: # Is an import_name pass else: if len(from_names) + 1 == len(import_path): # We have to fetch the from_names part first and then check # if from_names exists in the modules. from_import_name = import_path[-1] import_path = from_names importer = Importer(evaluator, tuple(import_path), module_context, import_node.level) types = importer.follow() #if import_node.is_nested() and not self.nested_resolve: # scopes = [NestedImportModule(module, import_node)] if not types: return NO_CONTEXTS if from_import_name is not None: types = unite( t.py__getattribute__( from_import_name, name_context=context, is_goto=is_goto, analysis_errors=False ) for t in types ) if not is_goto: types = ContextSet(types) if not types: path = import_path + [from_import_name] importer = Importer(evaluator, tuple(path), module_context, import_node.level) types = importer.follow() # goto only accepts `Name` if is_goto: types = set(s.name for s in types) else: # goto only accepts `Name` if is_goto: types = set(s.name for s in types) debug.dbg('after import: %s', types) return types
def infer_import(context, tree_name, is_goto=False): module_context = context.get_root_context() import_node = search_ancestor(tree_name, 'import_name', 'import_from') import_path = import_node.get_path_for_name(tree_name) from_import_name = None evaluator = context.evaluator try: from_names = import_node.get_from_names() except AttributeError: # Is an import_name pass else: if len(from_names) + 1 == len(import_path): # We have to fetch the from_names part first and then check # if from_names exists in the modules. from_import_name = import_path[-1] import_path = from_names importer = Importer(evaluator, tuple(import_path), module_context, import_node.level) types = importer.follow() #if import_node.is_nested() and not self.nested_resolve: # scopes = [NestedImportModule(module, import_node)] if not types: return NO_CONTEXTS if from_import_name is not None: types = unite( t.py__getattribute__( from_import_name, name_context=context, is_goto=is_goto, analysis_errors=False ) for t in types ) if not is_goto: types = ContextSet.from_set(types) if not types: path = import_path + [from_import_name] importer = Importer(evaluator, tuple(path), module_context, import_node.level) types = importer.follow() # goto only accepts `Name` if is_goto: types = set(s.name for s in types) else: # goto only accepts `Name` if is_goto: types = set(s.name for s in types) debug.dbg('after import: %s', types) return types
def defined_names(self): """ List sub-definitions (e.g., methods in class). :rtype: list of Definition """ defs = self._name.infer() return sorted( unite(defined_names(self._evaluator, d) for d in defs), key=lambda s: s._name.start_pos or (0, 0) )
def _goto(self, context, name): definition = name.get_definition(import_name_always=True) if definition is not None: type_ = definition.type if type_ == 'expr_stmt': # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return [TreeNameDefinition(context, name)] elif type_ == 'param': return [ParamName(context, name)] elif type_ in ('funcdef', 'classdef'): return [TreeNameDefinition(context, name)] elif type_ in ('import_from', 'import_name'): module_names = imports.infer_import(context, name, is_goto=True) return module_names else: contexts = self._follow_error_node_imports_if_possible(context, name) if contexts is not None: return [context.name for context in contexts] par = name.parent node_type = par.type if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': context_set = context.eval_node(trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] if to_evaluate[0] == 'await': to_evaluate.pop(0) context_set = context.eval_node(to_evaluate[0]) for trailer in to_evaluate[1:]: context_set = eval_trailer(context, context_set, trailer) param_names = [] for context in context_set: for signature in context.get_signatures(): for param_name in signature.get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif node_type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = context.eval_node(new_dotted) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) if node_type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) else: stmt = tree.search_ancestor( name, 'expr_stmt', 'lambdef' ) or name if stmt.type == 'lambdef': stmt = name return context.py__getattribute__( name, position=stmt.start_pos, search_global=True, is_goto=True )
def goto(self, context, name): definition = name.get_definition(import_name_always=True) if definition is not None: type_ = definition.type if type_ == 'expr_stmt': # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return [TreeNameDefinition(context, name)] elif type_ == 'param': return [ParamName(context, name)] elif type_ in ('funcdef', 'classdef'): return [TreeNameDefinition(context, name)] elif type_ in ('import_from', 'import_name'): module_names = imports.infer_import(context, name, is_goto=True) return module_names par = name.parent node_type = par.type if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': context_set = context.eval_node(trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] if to_evaluate[0] == 'await': to_evaluate.pop(0) context_set = context.eval_node(to_evaluate[0]) for trailer in to_evaluate[1:]: context_set = eval_trailer(context, context_set, trailer) param_names = [] for context in context_set: try: get_param_names = context.get_param_names except AttributeError: pass else: for param_name in get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif node_type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = context.eval_node(new_dotted) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) if node_type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) else: stmt = tree.search_ancestor( name, 'expr_stmt', 'lambdef' ) or name if stmt.type == 'lambdef': stmt = name return context.py__getattribute__( name, position=stmt.start_pos, search_global=True, is_goto=True )