forked from VimPlug/jedi
Rewrite get_definitions using evaluate.get_names_of_scope
- Definition.names is changed to Definition.name. - TestGetDefinitions.test_nested_definitions fails.
This commit is contained in:
@@ -7,9 +7,8 @@ interesting information about completion and goto operations.
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
import itertools
|
|
||||||
|
|
||||||
from _compatibility import unicode
|
from _compatibility import unicode, reduce
|
||||||
import cache
|
import cache
|
||||||
import dynamic
|
import dynamic
|
||||||
import recursion
|
import recursion
|
||||||
@@ -59,6 +58,9 @@ class BaseDefinition(object):
|
|||||||
def __init__(self, definition, start_pos):
|
def __init__(self, definition, start_pos):
|
||||||
self.start_pos = start_pos
|
self.start_pos = start_pos
|
||||||
self.definition = definition
|
self.definition = definition
|
||||||
|
"""
|
||||||
|
An instance of :class:`jedi.parsing_representation.Base` subclass.
|
||||||
|
"""
|
||||||
self.is_keyword = isinstance(definition, keywords.Keyword)
|
self.is_keyword = isinstance(definition, keywords.Keyword)
|
||||||
|
|
||||||
# generate a path to the definition
|
# generate a path to the definition
|
||||||
@@ -273,44 +275,38 @@ class Definition(BaseDefinition):
|
|||||||
super(Definition, self).__init__(definition, definition.start_pos)
|
super(Definition, self).__init__(definition, definition.start_pos)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def names(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
Name of variable/function/class/module.
|
Name of variable/function/class/module.
|
||||||
|
|
||||||
For example, for ``isinstance`` it returns ``['isinstance']``.
|
For example, for ``x = None`` it returns ``'x'``.
|
||||||
As it is possible to have multiple definition in a statement,
|
|
||||||
this attribute returns a list of string.
|
|
||||||
|
|
||||||
:rtype: list of str
|
:rtype: str or None
|
||||||
"""
|
"""
|
||||||
d = self.definition
|
d = self.definition
|
||||||
if isinstance(d, er.InstanceElement):
|
if isinstance(d, er.InstanceElement):
|
||||||
d = d.var
|
d = d.var
|
||||||
if isinstance(d, pr.Name):
|
|
||||||
d = d.parent
|
|
||||||
|
|
||||||
if isinstance(d, er.Array):
|
if isinstance(d, pr.Name):
|
||||||
return [unicode(d.type)]
|
return d.names[-1] if d.names else None
|
||||||
|
elif isinstance(d, er.Array):
|
||||||
|
return unicode(d.type)
|
||||||
elif isinstance(d, (pr.Class, er.Class, er.Instance,
|
elif isinstance(d, (pr.Class, er.Class, er.Instance,
|
||||||
er.Function, pr.Function)):
|
er.Function, pr.Function)):
|
||||||
return [unicode(d.name)]
|
return unicode(d.name)
|
||||||
elif isinstance(d, pr.Module):
|
elif isinstance(d, pr.Module):
|
||||||
return [self.module_name]
|
return self.module_name
|
||||||
elif isinstance(d, pr.Import):
|
elif isinstance(d, pr.Import):
|
||||||
def getname(name):
|
try:
|
||||||
try:
|
return d.get_defined_names()[0].names[-1]
|
||||||
return [name.names[-1]]
|
except AttributeError, IndexError:
|
||||||
except AttributeError:
|
return None
|
||||||
return []
|
|
||||||
return list(itertools.chain(*map(getname, d.get_defined_names())))
|
|
||||||
elif isinstance(d, pr.Statement):
|
elif isinstance(d, pr.Statement):
|
||||||
def getname(assignment):
|
try:
|
||||||
try:
|
return d.assignment_details[0][1].values[0][0].name.names[-1]
|
||||||
return [assignment[1].values[0][0].name.names[-1]]
|
except IndexError:
|
||||||
except IndexError:
|
return None
|
||||||
return []
|
return None
|
||||||
return list(itertools.chain(*map(getname, d.assignment_details)))
|
|
||||||
return []
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def description(self):
|
def description(self):
|
||||||
@@ -364,7 +360,12 @@ class Definition(BaseDefinition):
|
|||||||
|
|
||||||
:rtype: list of Definition
|
:rtype: list of Definition
|
||||||
"""
|
"""
|
||||||
return get_definitions(self.definition)
|
d = self.definition
|
||||||
|
if isinstance(d, er.InstanceElement):
|
||||||
|
d = d.var
|
||||||
|
if isinstance(d, pr.Name):
|
||||||
|
d = d.parent
|
||||||
|
return get_definitions(d)
|
||||||
|
|
||||||
|
|
||||||
def get_definitions(scope):
|
def get_definitions(scope):
|
||||||
@@ -374,15 +375,10 @@ def get_definitions(scope):
|
|||||||
:type scope: Scope
|
:type scope: Scope
|
||||||
:rtype: list of Definition
|
:rtype: list of Definition
|
||||||
"""
|
"""
|
||||||
def is_definition(s):
|
tuples = evaluate.get_names_of_scope(
|
||||||
return isinstance(s, (pr.Import, pr.Function, pr.Class)) or \
|
scope, star_search=False, include_builtin=False)
|
||||||
isinstance(s, pr.Statement) and s.assignment_details
|
names = reduce(lambda x, y: x + y[1], tuples, [])
|
||||||
scopes = []
|
return list(map(Definition, sorted(names, key=lambda s: s.start_pos)))
|
||||||
scopes.extend(scope.imports)
|
|
||||||
scopes.extend(scope.statements)
|
|
||||||
scopes.extend(scope.subscopes)
|
|
||||||
dscopes = sorted(filter(is_definition, scopes), key=lambda s: s.start_pos)
|
|
||||||
return list(map(Definition, dscopes))
|
|
||||||
|
|
||||||
|
|
||||||
class RelatedName(BaseDefinition):
|
class RelatedName(BaseDefinition):
|
||||||
|
|||||||
@@ -402,28 +402,23 @@ class TestGetDefinitions(TestBase):
|
|||||||
pass
|
pass
|
||||||
data = None
|
data = None
|
||||||
""")
|
""")
|
||||||
assert len(definitions) == 4
|
self.assertEqual([d.name for d in definitions],
|
||||||
assert definitions[0].names == ['module']
|
['module', 'Class', 'func', 'data'])
|
||||||
assert definitions[1].names == ['Class']
|
|
||||||
assert definitions[2].names == ['func']
|
|
||||||
assert definitions[3].names == ['data']
|
|
||||||
|
|
||||||
def test_multiple_assignment(self):
|
def test_multiple_assignment(self):
|
||||||
definitions = api.get_definitions("""
|
definitions = api.get_definitions("""
|
||||||
x = y = None
|
x = y = None
|
||||||
""")
|
""")
|
||||||
assert len(definitions) == 1
|
self.assertEqual([d.name for d in definitions],
|
||||||
assert definitions[0].names == ['x', 'y']
|
['x', 'y'])
|
||||||
|
|
||||||
def test_multiple_imports(self):
|
def test_multiple_imports(self):
|
||||||
definitions = api.get_definitions("""
|
definitions = api.get_definitions("""
|
||||||
from module import a, b
|
from module import a, b
|
||||||
from another_module import *
|
from another_module import *
|
||||||
""")
|
""")
|
||||||
assert len(definitions) == 3
|
self.assertEqual([d.name for d in definitions],
|
||||||
assert definitions[0].names == ['a']
|
['a', 'b'])
|
||||||
assert definitions[1].names == ['b']
|
|
||||||
assert definitions[2].names == []
|
|
||||||
|
|
||||||
def test_nested_definitions(self):
|
def test_nested_definitions(self):
|
||||||
definitions = api.get_definitions("""
|
definitions = api.get_definitions("""
|
||||||
@@ -433,13 +428,13 @@ class TestGetDefinitions(TestBase):
|
|||||||
def g():
|
def g():
|
||||||
pass
|
pass
|
||||||
""")
|
""")
|
||||||
assert len(definitions) == 1
|
self.assertEqual([d.name for d in definitions],
|
||||||
assert definitions[0].names == ['Class']
|
['Class'])
|
||||||
subdefinitions = definitions[0].get_definitions()
|
subdefinitions = definitions[0].get_definitions()
|
||||||
assert subdefinitions[0].names == ['f']
|
self.assertEqual([d.name for d in subdefinitions],
|
||||||
assert subdefinitions[1].names == ['g']
|
['f', 'g'])
|
||||||
assert subdefinitions[0].full_name == 'Class.f'
|
self.assertEqual([d.full_name for d in subdefinitions],
|
||||||
assert subdefinitions[1].full_name == 'Class.g'
|
['Class.f', 'Class.g'])
|
||||||
|
|
||||||
|
|
||||||
class TestSpeed(TestBase):
|
class TestSpeed(TestBase):
|
||||||
|
|||||||
Reference in New Issue
Block a user