Permalink
Browse files

Add inheritance to the python autocomplete plugin

  • Loading branch information...
goinnn committed Feb 26, 2012
1 parent 56891f8 commit a0dd2480e4cd7d43d6d1b0e2415c9dddb6894876
Showing with 72 additions and 30 deletions.
  1. +72 −30 kate_plugins/pyte_plugins/autocomplete/pyplete.py
@@ -70,50 +70,47 @@ def get_importables_rest_level(self, list_autocomplete, imp_name, subimportables
return list_autocomplete and bool(len(list_autocomplete))
def get_importables_from_text(self, list_autocomplete, text, line=None):
- code = compiler.parse(text)
- code_walk = compiler.walk(code, CodeFinder())
- modules = code_walk.modules
+ pysmell_modules = self.get_pysmell_modules_to_text(text)
treatment_dict = {'CONSTANTS': self.treatment_pysmell_const,
'FUNCTIONS': self.treatment_pysmell_func,
'CLASSES': self.treatment_pysmell_cls}
for key, func in treatment_dict.items():
- pysmell_items = modules[key]
+ pysmell_items = pysmell_modules[key]
if isinstance(pysmell_items, dict):
pysmell_items = pysmell_items.items()
for pysmell_item in pysmell_items:
- item = func(pysmell_item)
+ item = func(pysmell_item, pysmell_modules)
if not item in list_autocomplete:
list_autocomplete.append(item)
is_auto = len(list_autocomplete) > 0
if not is_auto and line:
line = "%s%s" % (PYSMELL_PREFIX, line.strip())
- for pointer in modules['POINTERS'].keys():
+ for pointer in pysmell_modules['POINTERS'].keys():
if pointer.startswith(line):
is_auto = is_auto or self.get_importables_from_line(list_autocomplete,
text, pointer.replace(PYSMELL_PREFIX, ''),
text_info=False)
return is_auto
def get_importables_from_line(self, list_autocomplete, text, code_line, text_info=True):
- code = compiler.parse(text)
- code_walk = compiler.walk(code, CodeFinder())
+ pysmell_modules = self.get_pysmell_modules_to_text(text)
code_line_split = code_line.split(self.separator)
prefix = code_line_split[0]
prfx_code_line = '%s%s' % (PYSMELL_PREFIX, prefix)
- if prfx_code_line in code_walk.modules['CONSTANTS']:
+ if prfx_code_line in pysmell_modules['CONSTANTS']:
return False
- elif code_walk.modules['CLASSES'].get(prfx_code_line, None) and not code_line_split[1:]:
- class_smell = code_walk.modules['CLASSES'].get(prfx_code_line)
- self.treatment_pysmell_into_cls(class_smell, list_autocomplete)
+ elif pysmell_modules['CLASSES'].get(prfx_code_line, None) and not code_line_split[1:]:
+ class_smell = pysmell_modules['CLASSES'].get(prfx_code_line)
+ self.treatment_pysmell_into_cls(class_smell, pysmell_modules, list_autocomplete)
return True
- elif prfx_code_line in [name for name, args, desc in code_walk.modules['FUNCTIONS']]:
- index_func = [f[0] for f in code_walk.modules['FUNCTIONS']].index(prfx_code_line)
- func_smell = code_walk.modules['FUNCTIONS'][index_func]
+ elif prfx_code_line in [name for name, args, desc in pysmell_modules['FUNCTIONS']]:
+ index_func = [f[0] for f in pysmell_modules['FUNCTIONS']].index(prfx_code_line)
+ func_smell = pysmell_modules['FUNCTIONS'][index_func]
list_autocomplete.append(self.treatment_pysmell_into_func(func_smell))
return True
- elif code_walk.modules['POINTERS'].get(prfx_code_line, None):
- module_path = code_walk.modules['POINTERS'].get(prfx_code_line, None)
+ elif pysmell_modules['POINTERS'].get(prfx_code_line, None):
+ module_path = pysmell_modules['POINTERS'].get(prfx_code_line, None)
module = module_path.split(self.separator)[0]
submodules = module_path.split(self.separator)[1:]
submodules.extend(code_line_split[1:])
@@ -129,7 +126,14 @@ def get_importables_from_line(self, list_autocomplete, text, code_line, text_inf
return self.get_importables_from_text(list_autocomplete, text, list_autocomplete)
return False
+ def get_pysmell_modules_to_text(self, text):
+ code = compiler.parse(text)
+ code_walk = compiler.walk(code, CodeFinder())
+ return code_walk.modules
+
def get_imp_loader_from_path(self, imp_name, subimportables, subimportables_undone=None):
+ if not imp_name in self.importables_path:
+ return (None, [])
imp_path = self.importables_path[imp_name][0]
subimportables_undone = subimportables_undone or []
subimportables_str = os.sep.join(subimportables)
@@ -143,14 +147,14 @@ def get_imp_loader_from_path(self, imp_name, subimportables, subimportables_undo
return (importable, subimportables_undone)
elif subimportables:
subimportables_undone.append(subimportables[-1])
- return self.get_module_from_path(imp_name, subimportables[:-1], subimportables_undone)
+ return self.get_imp_loader_from_path(imp_name, subimportables[:-1], subimportables_undone)
return (None, subimportables_undone)
- def treatment_pysmell_const(self, constant):
+ def treatment_pysmell_const(self, constant, modules=None):
constant = constant.replace(PYSMELL_PREFIX, '')
return self.func_info(constant, 'constant')
- def treatment_pysmell_func(self, func):
+ def treatment_pysmell_func(self, func, modules=None):
func_name, args, description = func
func_name = func_name.replace(PYSMELL_PREFIX, '')
args = ', '.join(args)
@@ -161,27 +165,65 @@ def treatment_pysmell_func(self, func):
def treatment_pysmell_into_func(self, func):
return self.treatment_pysmell_func(func)
- def treatment_pysmell_cls(self, cls):
- cls_name, info = cls
- cls_name = cls_name.replace(PYSMELL_PREFIX, '')
- args_constructor = info.get('constructor', None)
+ def treatment_pysmell_constructor(self, cls_name, args_constructor, description=None):
args_constructor = ', '.join(args_constructor)
args_constructor = ' (%s)' % args_constructor
- description = info.get('docstring', None)
return self.func_info(cls_name,
'class', args_constructor,
description)
- def treatment_pysmell_into_cls(self, cls, list_autocomplete):
+ def treatment_pysmell_cls(self, cls, modules):
+ cls_name, info = cls
+ cls_name = cls_name.replace(PYSMELL_PREFIX, '')
+ args_constructor = self.get_pysmell_constructor(info, modules)
+ return self.treatment_pysmell_constructor(cls_name, args_constructor, info.get('docstring', None))
+
+ def treatment_pysmell_into_cls(self, cls, modules, list_autocomplete, inherited_methods=None):
+ inherited_methods = inherited_methods or []
for m in cls['methods']:
- item = self.treatment_pysmell_func(m)
- if not item in list_autocomplete:
- list_autocomplete.append(item)
- for m in cls['constructor']:
+ if m[0] in inherited_methods:
+ continue
+ inherited_methods.append(m[0])
item = self.treatment_pysmell_func(m)
if not item in list_autocomplete:
list_autocomplete.append(item)
for m in cls['properties']:
item = self.treatment_pysmell_const(m)
if not item in list_autocomplete:
list_autocomplete.append(item)
+ bases = cls['bases']
+ for base in bases:
+ base_info = self.get_parent_pysmell_info(base, modules)
+ if base_info:
+ return self.treatment_pysmell_into_cls(base_info, modules,
+ list_autocomplete, inherited_methods)
+
+ def get_pysmell_constructor(self, info, modules):
+ constructor = info.get('constructor', None)
+ if constructor:
+ return constructor
+ bases = info['bases']
+ for base in bases:
+ if base == 'object':
+ continue
+ base_info = self.get_parent_pysmell_info(base, modules)
+ if not base_info:
+ continue
+ constructor = base_info.get('constructor', None)
+ if constructor:
+ return constructor
+ return self.get_pysmell_constructor(base_info, modules)
+ return ''
+
+ def get_parent_pysmell_info(self, base, modules):
+ cls_name = base.replace(PYSMELL_PREFIX, '')
+ base_info = modules['CLASSES'].get(base, None)
+ if not base_info:
+ base_path = base.split('.')
+ imp_loader, submodules_undone = self.get_imp_loader_from_path(base_path[0], base_path[1:])
+ if len(submodules_undone) != 1:
+ return None
+ cls_name = '%s%s' % (PYSMELL_PREFIX, submodules_undone[0])
+ base_info = self.get_pysmell_modules_to_text(imp_loader.get_source())['CLASSES'].get(cls_name, None)
+ return base_info
+

0 comments on commit a0dd248

Please sign in to comment.