diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 17261f2d..684165bf 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -263,6 +263,7 @@ class Script(object): if user_stmt is not None: eval_stmt.start_pos = user_stmt.end_pos scopes = self._evaluator.eval_statement(eval_stmt) + return scopes def _get_under_cursor_stmt(self, cursor_txt): @@ -387,10 +388,11 @@ class Script(object): if goto_path: definitions = set(self._prepare_goto(goto_path)) - definitions = resolve_import_paths(definitions) - d = set([classes.Definition(self._evaluator, s) for s in definitions - if s is not imports.ImportWrapper.GlobalNamespace]) - return helpers.sorted_definitions(d) + names = [s if isinstance(s, pr.Name) else s.name for s in definitions + if s is not imports.ImportWrapper.GlobalNamespace] + defs = [classes.Definition(self._evaluator, name.names[-1]) + for name in names] + return helpers.sorted_definitions(set(defs)) def goto_assignments(self): """ @@ -563,7 +565,7 @@ class Script(object): key_name = unicode(detail[0][0].name) except (IndexError, AttributeError): pass - return [classes.CallSignature(self._evaluator, o, call, index, key_name) + return [classes.CallSignature(self._evaluator, o.name.names[-1], call, index, key_name) for o in origins if hasattr(o, 'py__call__')] def _analysis(self): diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 8b4d1696..38c96761 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -330,7 +330,7 @@ class BaseDefinition(object): # Functions, classes and modules are already fixed definitions, we # cannot follow them anymore. return [self] - stmt_or_imp = self._definition.get_parent_until((pr.ExprStmt, pr.Import)) + stmt_or_imp = self._definition.get_parent_until((pr.Statement, pr.Import)) call_path = call_path_for_name_part(stmt_or_imp, self._definition) names = self._evaluator.goto(stmt_or_imp, call_path) return [Definition(self._evaluator, n) for n in names] @@ -708,9 +708,13 @@ class Definition(use_metaclass(CachedMetaClass, BaseDefinition)): # Currently only handle NameParts. Once we have a proper API, this # will be the standard anyway. raise NotImplementedError - stmt_or_imp = self._definition.get_parent_until((pr.ExprStmt, pr.Import)) - exp_list = stmt_or_imp.expression_list() - return not exp_list or self._definition.start_pos < exp_list[0].start_pos + _def = self._definition.get_parent_until((pr.ExprStmt, + pr.Import, pr.Function, pr.Class, pr.Module)) + if isinstance(_def, pr.ExprStmt): + exp_list = _def.expression_list() + return not exp_list or self._definition.start_pos < exp_list[0].start_pos + else: + return True def __eq__(self, other): return self._start_pos == other._start_pos \ diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 100f9c3a..a2dfa2cb 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -304,13 +304,13 @@ class FakeImport(pr.Import): class FakeName(pr.Name): - def __init__(self, name_or_names, parent=None): - p = 0, 0 + def __init__(self, name_or_names, parent=None, start_pos=(0, 0)): + start_pos = 0, 0 if isinstance(name_or_names, list): - names = [(n, p) for n in name_or_names] + names = [(n, start_pos) for n in name_or_names] else: - names = [(name_or_names, p)] - super(FakeName, self).__init__(FakeSubModule, names, p, p, parent) + names = [(name_or_names, start_pos)] + super(FakeName, self).__init__(FakeSubModule, names, start_pos, start_pos, parent) def get_definition(self): return self.parent diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 1a7585dc..d5583302 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -128,6 +128,10 @@ class Array(use_metaclass(CachedMetaClass, IterableWrapper)): self._evaluator = evaluator self._array = array + @property + def name(self): + return helpers.FakeName(self._array.type, parent=self) + def py__bool__(self): return None # We don't know the length, because of appends. diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 60321da3..bf0c8d78 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -35,6 +35,7 @@ from jedi.parser import representation as pr from jedi.parser.tokenize import Token from jedi import debug from jedi import common +from jedi.cache import underscore_memoization from jedi.evaluate.cache import memoize_default, CachedMetaClass from jedi.evaluate import compiled from jedi.evaluate import recursion @@ -218,8 +219,14 @@ class Instance(use_metaclass(CachedMetaClass, Executed)): debug.warning('No __getitem__, cannot access the array.') return [] + @property + @underscore_memoization + def name(self): + name = self.base.name + return helpers.FakeName(unicode(name), self, name.start_pos) + def __getattr__(self, name): - if name not in ['start_pos', 'end_pos', 'name', 'get_imports', + if name not in ['start_pos', 'end_pos', 'get_imports', 'doc', 'raw_doc', 'asserts']: raise AttributeError("Instance %s: Don't touch this (%s)!" % (self, name))