1
0
forked from VimPlug/jedi

Better goto for imports, which helps usages.

This commit is contained in:
Dave Halter
2014-12-03 16:15:31 +01:00
parent 536c188192
commit 6bf154de5e
5 changed files with 27 additions and 16 deletions

View File

@@ -503,7 +503,7 @@ class Script(object):
import_name = user_stmt.get_defined_names() import_name = user_stmt.get_defined_names()
# imports have only one name # imports have only one name
np = import_name[0] np = import_name[0]
if not user_stmt.star and unicode(name_part) == unicode(np): if not user_stmt.is_star_import() and unicode(name_part) == unicode(np):
definitions.append(np) definitions.append(np)
else: else:
# The Evaluator.goto function checks for definitions, but since we # The Evaluator.goto function checks for definitions, but since we
@@ -549,12 +549,7 @@ class Script(object):
names = usages.usages(self._evaluator, definitions, module) names = usages.usages(self._evaluator, definitions, module)
for d in set(definitions): for d in set(definitions):
try: names.append(classes.Definition(self._evaluator, d))
name_part = d.names[-1]
except AttributeError:
names.append(classes.Definition(self._evaluator, d))
else:
names.append(classes.Definition(self._evaluator, name_part))
finally: finally:
settings.dynamic_flow_information = temp settings.dynamic_flow_information = temp

View File

@@ -1,5 +1,4 @@
from jedi._compatibility import u, unicode from jedi._compatibility import u, unicode
from jedi import common
from jedi.api import classes from jedi.api import classes
from jedi.parser import tree as pr from jedi.parser import tree as pr
from jedi.evaluate import imports from jedi.evaluate import imports
@@ -101,7 +100,6 @@ def usages_add_import_modules(evaluator, definitions):
for d in definitions: for d in definitions:
imp_or_stmt = d.get_definition() imp_or_stmt = d.get_definition()
if isinstance(imp_or_stmt, pr.Import): if isinstance(imp_or_stmt, pr.Import):
s = imports.ImportWrapper(evaluator, imp_or_stmt, nested_resolve=True) s = imports.ImportWrapper(evaluator, d)
with common.ignored(IndexError): new |= s.follow(is_goto=True)
new.add(s.follow(is_goto=True)[0])
return set(definitions) | new return set(definitions) | new

View File

@@ -85,6 +85,7 @@ from jedi.evaluate import finder
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import precedence from jedi.evaluate import precedence
from jedi.evaluate import param from jedi.evaluate import param
from jedi.evaluate import helpers
from jedi.evaluate.helpers import FakeStatement, deep_ast_copy, call_of_name from jedi.evaluate.helpers import FakeStatement, deep_ast_copy, call_of_name
@@ -455,21 +456,37 @@ class Evaluator(object):
return self.eval_element(call) return self.eval_element(call)
def goto(self, name): def goto(self, name):
def resolve_implicit_imports(names):
for name in names:
if isinstance(name, helpers.FakeName):
# Those are implicit imports.
s = imports.ImportWrapper(self, name)
for n in s.follow(is_goto=True):
yield n
yield name
imp = name.get_definition()
stmt = name.parent stmt = name.parent
if isinstance(stmt, pr.ExprStmt) and name in stmt.get_defined_names(): if isinstance(stmt, pr.ExprStmt) and name in stmt.get_defined_names():
# TODO remove? I think this is never called.
return [name] return [name]
elif isinstance(stmt, (pr.Param, pr.Function, pr.Class)) and stmt.name is name: elif isinstance(stmt, (pr.Param, pr.Function, pr.Class)) and stmt.name is name:
return [name] return [name]
elif isinstance(imp, pr.Import):
return imports.ImportWrapper(self, name).follow(is_goto=True)
scope = name.get_parent_scope() scope = name.get_parent_scope()
if pr.is_node(name.parent, 'trailer'): if pr.is_node(name.parent, 'trailer'):
call = call_of_name(name, cut_own_trailer=True) call = call_of_name(name, cut_own_trailer=True)
types = self.eval_element(call) types = self.eval_element(call)
return iterable.unite(self.find_types(typ, name, is_goto=True) return resolve_implicit_imports(iterable.unite(
for typ in types) self.find_types(typ, name, is_goto=True) for typ in types
))
else: else:
return self.find_types(scope, name, name.start_pos, return self.find_types(scope, name, name.start_pos,
search_global=True, is_goto=True) search_global=True, is_goto=True)
if isinstance(stmt, pr.Import): if isinstance(stmt, pr.Import):
# Nowhere to goto for aliases # Nowhere to goto for aliases
if stmt.alias == call_path[0]: if stmt.alias == call_path[0]:

View File

@@ -768,7 +768,7 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)):
@property @property
@memoize_default() @memoize_default()
def name(self): def name(self):
return helpers.FakeName(unicode(self.base.name), self) return helpers.FakeName(unicode(self.base.name), self, (1, 0))
@memoize_default() @memoize_default()
def _sub_modules(self): def _sub_modules(self):

View File

@@ -49,11 +49,12 @@ class Abc():
Abc.d.Abc Abc.d.Abc
#< 4 (0,4), (4,1) #< 4 (0,4), (5,1)
def blubi(): def blubi():
pass
#< (-4,4), (0,1) #< (-5,4), (0,1)
@blubi @blubi
def a(): pass def a(): pass