diff --git a/jedi/fast_parser.py b/jedi/fast_parser.py index 374a866e..8509dc5e 100644 --- a/jedi/fast_parser.py +++ b/jedi/fast_parser.py @@ -188,6 +188,16 @@ class FastParser(use_metaclass(CachedFastParser)): self._parse(code) + def scan_user_scope(self, sub_module): + """ Scan with self.user_position. + :type sub_module: parsing.SubModule + """ + for scope in sub_module.statements + sub_module.subscopes: + if isinstance(scope, parsing.Scope): + if scope.start_pos <= self.user_position <= scope.end_pos: + return self.scan_user_scope(scope) or scope + return None + def _parse(self, code): """ :type code: str """ r = r'(?:\n(?:def|class|@.*?\n(?:def|class))|^).*?' \ @@ -215,19 +225,25 @@ class FastParser(use_metaclass(CachedFastParser)): # check if code_part has already been parsed h = hash(code_part) - p = None if h in hashes and hashes[h].code == code_part: p = hashes[h] + del hashes[h] m = p.module m.line_offset += line_offset + 1 - m.start_pos[0] if self.user_position is not None and \ m.start_pos <= self.user_position <= m.end_pos: + # It's important to take care of the whole user + # positioning stuff. #print(h, line_offset, m.start_pos, lines) - p = None - else: - del hashes[h] - - if p is None: + #p = None + p.user_stmt = m.get_statement_for_position( + self.user_position, include_imports=True) + if p.user_stmt: + p.user_scope = p.user_stmt.parent + else: + p.user_scope = self.scan_user_scope(m) \ + or self.module + else: p = parsing.PyFuzzyParser(code[start:], self.module_path, self.user_position, line_offset=line_offset, stop_on_scope=True, diff --git a/jedi/parsing.py b/jedi/parsing.py index a2935803..457e8a77 100644 --- a/jedi/parsing.py +++ b/jedi/parsing.py @@ -221,16 +221,18 @@ class Scope(Simple): return not (self.imports or self.subscopes or self.statements) @Python3Method - def get_statement_for_position(self, pos): + def get_statement_for_position(self, pos, include_imports=False): checks = self.statements + self.asserts + if include_imports: + checks += self.imports if self.isinstance(Function): checks += self.params + self.decorators + self.returns for s in checks: if isinstance(s, Flow): - p = s.get_statement_for_position(pos) + p = s.get_statement_for_position(pos, include_imports) while s.next and not p: s = s.next - p = s.get_statement_for_position(pos) + p = s.get_statement_for_position(pos, include_imports) if p: return p elif s.start_pos <= pos < s.end_pos: @@ -238,7 +240,7 @@ class Scope(Simple): for s in self.subscopes: if s.start_pos <= pos <= s.end_pos: - p = s.get_statement_for_position(pos) + p = s.get_statement_for_position(pos, include_imports) if p: return p