Actual forward reference annotations are working pretty smooth now.

This commit is contained in:
Dave Halter
2015-12-20 22:57:24 +01:00
parent c4906e0e3f
commit 5791860861
5 changed files with 16 additions and 11 deletions

View File

@@ -322,12 +322,10 @@ class Script(object):
@memoize_default()
def _get_under_cursor_stmt(self, cursor_txt, start_pos=None):
node = Parser(self._grammar, cursor_txt, 'eval_input').get_parsed_node()
if node is None:
stmt = Parser(self._grammar, cursor_txt, 'eval_input').get_parsed_node()
if stmt is None:
return None
stmt = node.children[0]
user_stmt = self._parser.user_stmt()
if user_stmt is None:
# Set the start_pos to a pseudo position, that doesn't exist but

View File

@@ -305,6 +305,8 @@ class Evaluator(object):
types = set(chain.from_iterable(self.find_types(typ, next_name)
for typ in types))
types = types
elif element.type == 'eval_input':
types = self._eval_element_not_cached(element.children[0])
else:
types = precedence.calculate_children(self, element.children)
debug.dbg('eval_element result %s', types)

View File

@@ -32,7 +32,7 @@ def _evaluate_for_annotation(evaluator, annotation):
for definition in evaluator.eval_element(annotation):
if (isinstance(definition, CompiledObject) and
isinstance(definition.obj, str)):
p = Parser(load_grammar(), definition.obj, start='expr')
p = Parser(load_grammar(), definition.obj, start='eval_input')
element = p.get_parsed_node()
if element is None:
debug.warning('Annotation not parsed: %s' % definition.obj)

View File

@@ -14,7 +14,7 @@ from jedi.common import unite
from jedi.evaluate import compiled
from jedi.evaluate import representation as er
from jedi.evaluate import iterable
from jedi.parser import Parser
from jedi.parser import ParserWithRecovery
from jedi.parser import tree
from jedi import debug
from jedi.evaluate import precedence
@@ -243,7 +243,7 @@ def collections_namedtuple(evaluator, obj, arguments):
)
# Parse source
generated_class = Parser(evaluator.grammar, unicode(source)).module.subscopes[0]
generated_class = ParserWithRecovery(evaluator.grammar, unicode(source)).module.subscopes[0]
return set([er.Class(evaluator, generated_class)])

View File

@@ -41,14 +41,19 @@ def test_simple_annotations():
@pytest.mark.parametrize('reference', [
'assert 1',
'1',
'lambda: 3',
'def x(): pass',
'1, 2',
r'1\n'
])
def test_illegal_forward_references(reference):
source = """
def foo(bar: "%s"):
bar""" % reference
source = 'def foo(bar: "%s"): bar' % reference
assert not jedi.Script(source).goto_definitions()
def test_lambda_forward_references():
source = 'def foo(bar: "lambda: 3"): bar'
# For now just receiving the 3 is ok. I'm doubting that this is what we
# want. We also execute functions. Should we only execute classes?
assert jedi.Script(source).goto_definitions()