def _prepare_goto(self, goto_path, is_completion=False): """ Base for completions/goto. Basically it returns the resolved scopes under cursor. """ debug.dbg('start: %s in %s', goto_path, self._parser.user_scope()) user_stmt = self._parser.user_stmt_with_whitespace() if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, # something's strange. Most probably the backwards tokenizer # matched to much. return [] if isinstance(user_stmt, pr.Import): scopes = [ helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt, is_completion)[0] ] else: # just parse one statement, take it and evaluate it eval_stmt = self._get_under_cursor_stmt(goto_path) if not is_completion: # goto_definition returns definitions of its statements if the # cursor is on the assignee. By changing the start_pos of our # "pseud" statement, the Jedi evaluator can find the assignees. if user_stmt is not None: eval_stmt.start_pos = user_stmt.end_pos scopes = self._evaluator.eval_statement(eval_stmt) return scopes
def _prepare_goto(self, goto_path, is_completion=False): """ Base for completions/goto. Basically it returns the resolved scopes under cursor. """ debug.dbg('start: %s in %s', goto_path, self._parser.user_scope()) user_stmt = self._parser.user_stmt_with_whitespace() if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, # something's strange. Most probably the backwards tokenizer # matched to much. return [] if isinstance(user_stmt, pr.Import): scopes = [helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt, is_completion)[0]] else: # just parse one statement, take it and evaluate it eval_stmt = self._get_under_cursor_stmt(goto_path) if not is_completion: # goto_definition returns definitions of its statements if the # cursor is on the assignee. By changing the start_pos of our # "pseud" statement, the Jedi evaluator can find the assignees. if user_stmt is not None: eval_stmt.start_pos = user_stmt.end_pos scopes = self._evaluator.eval_statement(eval_stmt) return scopes
def _prepare_goto(self, goto_path, is_completion=False): """ Base for completions/goto. Basically it returns the resolved scopes under cursor. """ debug.dbg('start: %s in %s', goto_path, self._parser.user_scope()) user_stmt = self._parser.user_stmt_with_whitespace() if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, # something's strange. Most probably the backwards tokenizer # matched to much. return [] if isinstance(user_stmt, pr.Import): i, _ = helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt, is_completion) if i is None: return [] scopes = [i] else: # just parse one statement, take it and evaluate it eval_stmt = self._get_under_cursor_stmt(goto_path) if eval_stmt is None: return [] module = self._parser.module() names, level, _, _ = helpers.check_error_statements(module, self._pos) if names: i = imports.get_importer(self._evaluator, names, module, level) return i.follow(self._evaluator) scopes = self._evaluator.eval_element(eval_stmt) return scopes
def _prepare_goto(self, goto_path, is_completion=False): """ Base for completions/goto. Basically it returns the resolved scopes under cursor. """ debug.dbg('start: %s in %s', goto_path, self._parser.user_scope()) user_stmt = self._parser.user_stmt_with_whitespace() if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, # something's strange. Most probably the backwards tokenizer # matched to much. return [] if isinstance(user_stmt, pr.Import): scopes = [ helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt, is_completion)[0] ] else: # just parse one statement, take it and evaluate it eval_stmt = self._get_under_cursor_stmt(goto_path) if eval_stmt is None: return [] module = self._parser.module() names, level, _, _ = helpers.check_error_statements( module, self._pos) if names: i = imports.get_importer(self._evaluator, names, module, level) return i.follow(self._evaluator) scopes = self._evaluator.eval_statement(eval_stmt) return scopes
def _goto(self, add_import_name=False): """ Used for goto_assignments and usages. :param add_import_name: Add the the name (if import) to the result. """ def follow_inexistent_imports(defs): """ Imports can be generated, e.g. following `multiprocessing.dummy` generates an import dummy in the multiprocessing module. The Import doesn't exist -> follow. """ definitions = set(defs) for d in defs: if isinstance(d.parent, pr.Import) \ and d.start_pos == (0, 0): i = imports.ImportPath(self._evaluator, d.parent).follow(is_goto=True) definitions.remove(d) definitions |= follow_inexistent_imports(i) return definitions goto_path = self._user_context.get_path_under_cursor() context = self._user_context.get_context() user_stmt = self._parser.user_stmt() if next(context) in ('class', 'def'): user_scope = self._parser.user_scope() definitions = set([user_scope.name]) search_name = unicode(user_scope.name) elif isinstance(user_stmt, pr.Import): s, name_part = helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt) try: definitions = [s.follow(is_goto=True)[0]] except IndexError: definitions = [] search_name = unicode(name_part) if add_import_name: import_name = user_stmt.get_defined_names() # imports have only one name if not user_stmt.star \ and name_part == import_name[0].names[-1]: definitions.append(import_name[0]) else: stmt = self._get_under_cursor_stmt(goto_path) defs, search_name = self._evaluator.goto(stmt) definitions = follow_inexistent_imports(defs) if isinstance(user_stmt, pr.Statement): c = user_stmt.expression_list() if c and not isinstance(c[0], (str, unicode)) \ and c[0].start_pos > self._pos \ and not re.search(r'\.\w+$', goto_path): # The cursor must be after the start, otherwise the # statement is just an assignee. definitions = [user_stmt] return definitions, search_name
def _prepare_goto(self, goto_path, is_completion=False): """ Base for completions/goto. Basically it returns the resolved scopes under cursor. """ debug.dbg('start: %s in %s', goto_path, self._parser.user_scope()) user_stmt = self._parser.user_stmt_with_whitespace() if not user_stmt and len(goto_path.split('\n')) > 1: # If the user_stmt is not defined and the goto_path is multi line, # something's strange. Most probably the backwards tokenizer # matched to much. return [] if isinstance(user_stmt, pr.Import): scopes = [helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt, is_completion)[0]] else: # just parse one statement, take it and evaluate it stmt = self._get_under_cursor_stmt(goto_path) scopes = self._evaluator.eval_statement(stmt) return scopes
def _goto(self, add_import_name=False): """ Used for goto_assignments and usages. :param add_import_name: Add the the name (if import) to the result. """ def follow_inexistent_imports(defs): """ Imports can be generated, e.g. following `multiprocessing.dummy` generates an import dummy in the multiprocessing module. The Import doesn't exist -> follow. """ definitions = set(defs) for d in defs: if isinstance(d.parent, tree.Import) \ and d.start_pos == (0, 0): i = imports.ImportWrapper(self._evaluator, d.parent).follow(is_goto=True) definitions.remove(d) definitions |= follow_inexistent_imports(i) return definitions goto_path = self._user_context.get_path_under_cursor() context = self._user_context.get_context() user_stmt = self._parser.user_stmt() user_scope = self._parser.user_scope() stmt = self._get_under_cursor_stmt(goto_path) if stmt is None: return [] if user_scope is None: last_name = None else: # Try to use the parser if possible. last_name = user_scope.name_for_position(self._pos) if last_name is None: last_name = stmt while not isinstance(last_name, tree.Name): try: last_name = last_name.children[-1] except AttributeError: # Doesn't have a name in it. return [] if next(context) in ('class', 'def'): # The cursor is on a class/function name. user_scope = self._parser.user_scope() definitions = set([user_scope.name]) elif isinstance(user_stmt, tree.Import): s, name = helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt) definitions = self._evaluator.goto(name) else: # The Evaluator.goto function checks for definitions, but since we # use a reverse tokenizer, we have new name_part objects, so we # have to check the user_stmt here for positions. if isinstance(user_stmt, tree.ExprStmt) \ and isinstance(last_name.parent, tree.ExprStmt): for name in user_stmt.get_defined_names(): if name.start_pos <= self._pos <= name.end_pos: return [name] defs = self._evaluator.goto(last_name) definitions = follow_inexistent_imports(defs) return definitions
def _goto(self, add_import_name=False): """ Used for goto_assignments and usages. :param add_import_name: Add the the name (if import) to the result. """ def follow_inexistent_imports(defs): """ Imports can be generated, e.g. following `multiprocessing.dummy` generates an import dummy in the multiprocessing module. The Import doesn't exist -> follow. """ definitions = set(defs) for d in defs: if isinstance(d.parent, pr.Import) \ and d.start_pos == (0, 0): i = imports.ImportWrapper(self._evaluator, d.parent).follow(is_goto=True) definitions.remove(d) definitions |= follow_inexistent_imports(i) return definitions goto_path = self._user_context.get_path_under_cursor() context = self._user_context.get_context() user_stmt = self._parser.user_stmt() if next(context) in ('class', 'def'): user_scope = self._parser.user_scope() definitions = set([user_scope.name]) search_name = unicode(user_scope.name) elif isinstance(user_stmt, pr.Import): s, name_part = helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt) try: definitions = [s.follow(is_goto=True)[0]] except IndexError: definitions = [] search_name = unicode(name_part) if add_import_name: import_name = user_stmt.get_defined_names() # imports have only one name if not user_stmt.star \ and unicode(name_part) == unicode(import_name[0].names[-1]): definitions.append(import_name[0]) else: stmt = self._get_under_cursor_stmt(goto_path) def test_lhs(): """ Special rule for goto, left hand side of the statement returns itself, if the name is ``foo``, but not ``foo.bar``. """ if isinstance(user_stmt, pr.Statement): for name in user_stmt.get_defined_names(): if name.start_pos <= self._pos <= name.end_pos \ and len(name.names) == 1: return name, unicode(name.names[-1]) return None, None lhs, search_name = test_lhs() if lhs is None: expression_list = stmt.expression_list() if len(expression_list) == 0: return [], '' # Only the first command is important, the rest should basically not # happen except in broken code (e.g. docstrings that aren't code). call = expression_list[0] if isinstance(call, pr.Call): call_path = list(call.generate_call_path()) else: call_path = [call] defs, search_name_part = self._evaluator.goto(stmt, call_path) search_name = unicode(search_name_part) definitions = follow_inexistent_imports(defs) else: definitions = [lhs] if isinstance(user_stmt, pr.Statement): c = user_stmt.expression_list() if c and not isinstance(c[0], (str, unicode)) \ and c[0].start_pos > self._pos \ and not re.search(r'\.\w+$', goto_path): # The cursor must be after the start, otherwise the # statement is just an assignee. definitions = [user_stmt] return definitions, search_name
def _goto(self, add_import_name=False): """ Used for goto_assignments and usages. :param add_import_name: Add the the name (if import) to the result. """ def follow_inexistent_imports(defs): """ Imports can be generated, e.g. following `multiprocessing.dummy` generates an import dummy in the multiprocessing module. The Import doesn't exist -> follow. """ definitions = set(defs) for d in defs: if isinstance(d.parent, pr.Import) \ and d.start_pos == (0, 0): i = imports.ImportWrapper(self._evaluator, d.parent).follow(is_goto=True) definitions.remove(d) definitions |= follow_inexistent_imports(i) return definitions goto_path = self._user_context.get_path_under_cursor() context = self._user_context.get_context() user_stmt = self._parser.user_stmt() stmt = self._get_under_cursor_stmt(goto_path) expression_list = stmt.expression_list() if len(expression_list) == 0: return [] # The reverse tokenizer only generates parses call. assert len(expression_list) == 1 call = expression_list[0] if isinstance(call, pr.Call): call_path = list(call.generate_call_path()) else: # goto_assignments on Operator returns nothing. return [] if next(context) in ('class', 'def'): # The cursor is on a class/function name. user_scope = self._parser.user_scope() definitions = set([user_scope.name]) elif isinstance(user_stmt, pr.Import): s, name_part = helpers.get_on_import_stmt(self._evaluator, self._user_context, user_stmt) try: definitions = [s.follow(is_goto=True)[0]] except IndexError: definitions = [] if add_import_name: import_name = user_stmt.get_defined_names() # imports have only one name np = import_name[0] if not user_stmt.star and unicode(name_part) == unicode(np): definitions.append(np) else: # The Evaluator.goto function checks for definitions, but since we # use a reverse tokenizer, we have new name_part objects, so we # have to check the user_stmt here for positions. if isinstance(user_stmt, pr.ExprStmt): for name in user_stmt.get_defined_names(): if name.start_pos <= self._pos <= name.end_pos \ and (not isinstance(name.parent, pr.Call) or name.parent.next is None): return [name] defs = self._evaluator.goto(stmt, call_path) definitions = follow_inexistent_imports(defs) return definitions