Make it possible to do class context completions even for non functions. Fixes #639.

This commit is contained in:
Dave Halter
2016-08-01 23:12:43 +02:00
parent abaa9732eb
commit 9acb5cf1b3
2 changed files with 26 additions and 10 deletions

View File

@@ -157,19 +157,14 @@ class Completion:
elif nodes and nodes[-1] in ('as', 'def', 'class'):
# No completions for ``with x as foo`` and ``import x as foo``.
# Also true for defining names as a class or function.
leaf = self._module.get_leaf_for_position(self._position)
cls = leaf.get_parent_until(tree.Class)
if isinstance(cls, (tree.Class, tree.Function)):
# Complete the methods that are defined in the super classes.
cls = self._evaluator.wrap(cls)
return list(self._get_class_context_completions(cls))
return []
return list(self._get_class_context_completions(is_function=True))
elif symbol_names[-1] == 'trailer' and nodes[-1] == '.':
dot = self._module.get_leaf_for_position(self._position)
atom_expr = call_of_leaf(dot.get_previous_leaf())
completion_names += self._trailer_completions(atom_expr)
else:
completion_names += self._global_completions()
completion_names += self._get_class_context_completions(is_function=False)
if 'trailer' in symbol_names:
call_signatures = self._call_signatures_method()
@@ -236,15 +231,26 @@ class Completion:
i = imports.Importer(self._evaluator, names, self._module, level)
return i.completion_names(self._evaluator, only_modules=only_modules)
def _get_class_context_completions(self, cls):
def _get_class_context_completions(self, is_function=True):
"""
Autocomplete inherited methods when overriding in child class.
"""
leaf = self._module.get_leaf_for_position(self._position, include_prefixes=True)
cls = leaf.get_parent_until(tree.Class)
if isinstance(cls, (tree.Class, tree.Function)):
# Complete the methods that are defined in the super classes.
cls = self._evaluator.wrap(cls)
else:
return
if cls.start_pos[1] >= leaf.start_pos[1]:
return
names_dicts = cls.names_dicts(search_global=False, is_instance=True)
# The first dict is the dictionary of class itself.
next(names_dicts)
for names_dict in names_dicts:
for values in names_dict.values():
for value in values:
if value.parent.type == 'funcdef':
if (value.parent.type == 'funcdef') == is_function:
yield value

View File

@@ -1,4 +1,8 @@
class X():
class Base():
myfoobar = 3
class X(Base):
def func(self, foo):
pass
@@ -20,3 +24,9 @@ class Y(X):
#? []
def mro
#? ['myfoobar']
myfoobar
#? []
myfoobar