Skip to content

Commit

Permalink
Add inheritance to the python autocomplete plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
goinnn committed Feb 26, 2012
1 parent 56891f8 commit a0dd248
Showing 1 changed file with 72 additions and 30 deletions.
102 changes: 72 additions & 30 deletions kate_plugins/pyte_plugins/autocomplete/pyplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:])
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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.