Remove the user_scope from the user_context module.

This commit is contained in:
Dave Halter
2016-06-27 08:35:24 +02:00
parent bb4ab45131
commit 0445d51d34
5 changed files with 30 additions and 28 deletions

View File

@@ -229,7 +229,7 @@ class Script(object):
temp, settings.dynamic_flow_information = \ temp, settings.dynamic_flow_information = \
settings.dynamic_flow_information, False settings.dynamic_flow_information, False
try: try:
user_stmt = self._parser.user_stmt() user_stmt = self._get_module().get_statement_for_position(self._pos)
definitions = self._goto() definitions = self._goto()
if not definitions and isinstance(user_stmt, tree.Import): if not definitions and isinstance(user_stmt, tree.Import):
# For not defined imports (goto doesn't find something, we take # For not defined imports (goto doesn't find something, we take

View File

@@ -53,6 +53,26 @@ def filter_names(evaluator, completion_names, like_name):
yield new yield new
def get_user_scope(module, position):
"""
Returns the scope in which the user resides. This includes flows.
"""
user_stmt = module.get_statement_for_position(position)
if user_stmt is None:
def scan(scope):
for s in scope.children:
if s.start_pos <= position <= s.end_pos:
if isinstance(s, (tree.Scope, tree.Flow)):
return scan(s) or s
elif s.type in ('suite', 'decorated'):
return scan(s)
return None
return scan(module) or module
else:
return user_stmt.get_parent_scope(include_flows=True)
class Completion: class Completion:
def __init__(self, evaluator, parser, code_lines, position, call_signatures_method): def __init__(self, evaluator, parser, code_lines, position, call_signatures_method):
self._evaluator = evaluator self._evaluator = evaluator
@@ -158,7 +178,7 @@ class Completion:
yield keywords.keyword(self._evaluator, k).name yield keywords.keyword(self._evaluator, k).name
def _global_completions(self): def _global_completions(self):
scope = self._parser.user_scope() scope = get_user_scope(self._module, self._position)
if not scope.is_scope(): # Might be a flow (if/while/etc). if not scope.is_scope(): # Might be a flow (if/while/etc).
scope = scope.get_parent_scope() scope = scope.get_parent_scope()
names_dicts = global_names_dict_generator( names_dicts = global_names_dict_generator(

View File

@@ -5,7 +5,6 @@ from collections import namedtuple
from jedi import cache from jedi import cache
from jedi.parser import ParserWithRecovery from jedi.parser import ParserWithRecovery
from jedi.parser.fast import FastParser from jedi.parser.fast import FastParser
from jedi.parser import tree
# TODO this should be part of the tokenizer not just of this user_context. # TODO this should be part of the tokenizer not just of this user_context.
Token = namedtuple('Token', ['type', 'string', 'start_pos', 'prefix']) Token = namedtuple('Token', ['type', 'string', 'start_pos', 'prefix'])
@@ -38,25 +37,5 @@ class UserContextParser(object):
self._parser_done_callback(parser) self._parser_done_callback(parser)
return parser return parser
@cache.underscore_memoization
def user_scope(self):
"""
Returns the scope in which the user resides. This includes flows.
"""
user_stmt = self.module().get_statement_for_position(self._position)
if user_stmt is None:
def scan(scope):
for s in scope.children:
if s.start_pos <= self._position <= s.end_pos:
if isinstance(s, (tree.Scope, tree.Flow)):
return scan(s) or s
elif s.type in ('suite', 'decorated'):
return scan(s)
return None
return scan(self.module()) or self.module()
else:
return user_stmt.get_parent_scope(include_flows=True)
def module(self): def module(self):
return self._parser().module return self._parser().module

View File

@@ -188,7 +188,10 @@ class IntegrationTestCase(object):
parser = Parser(load_grammar(), string, start_symbol='eval_input') parser = Parser(load_grammar(), string, start_symbol='eval_input')
parser.position_modifier.line = self.line_nr parser.position_modifier.line = self.line_nr
element = parser.get_parsed_node() element = parser.get_parsed_node()
element.parent = script._parser.user_scope() element.parent = jedi.api.completion.get_user_scope(
script._get_module(),
(self.line_nr, self.column)
)
results = evaluator.eval_element(element) results = evaluator.eval_element(element)
if not results: if not results:
raise Exception('Could not resolve %s on line %s' raise Exception('Could not resolve %s on line %s'

View File

@@ -4,7 +4,6 @@ import sys
import jedi import jedi
from jedi._compatibility import u, is_py3 from jedi._compatibility import u, is_py3
from jedi.parser import ParserWithRecovery, load_grammar from jedi.parser import ParserWithRecovery, load_grammar
from jedi.parser.user_context import UserContextParser
from jedi.parser import tree as pt from jedi.parser import tree as pt
from textwrap import dedent from textwrap import dedent
@@ -15,9 +14,10 @@ def test_user_statement_on_import():
" time)") " time)")
for pos in [(2, 1), (2, 4)]: for pos in [(2, 1), (2, 4)]:
p = UserContextParser(load_grammar(), s, None, pos, lambda x: 1).user_stmt() p = ParserWithRecovery(load_grammar(), s)
assert isinstance(p, pt.Import) stmt = p.module.get_statement_for_position(pos)
assert [str(n) for n in p.get_defined_names()] == ['time'] assert isinstance(stmt, pt.Import)
assert [str(n) for n in stmt.get_defined_names()] == ['time']
class TestCallAndName(): class TestCallAndName():