def _check_exceptional_conditions(self): if self.info.element_already_exists(): raise exceptions.RefactoringError( 'Element <%s> already exists.' % self.name) if not self.info.primary_is_found(): raise exceptions.RefactoringError( 'Cannot determine the scope <%s> should be defined in.' % self.name)
def create_move(project, resource, offset=None): """A factory for creating Move objects Based on `resource` and `offset`, return one of `MoveModule`, `MoveGlobal` or `MoveMethod` for performing move refactoring. """ if offset is None: return MoveModule(project, resource) this_pymodule = project.get_pymodule(resource) pyname = evaluate.eval_location(this_pymodule, offset) if pyname is None: raise exceptions.RefactoringError( 'Move only works on classes, functions, modules and methods.') pyobject = pyname.get_object() if isinstance(pyobject, pyobjects.PyModule) or \ isinstance(pyobject, pyobjects.PyPackage): return MoveModule(project, pyobject.get_resource()) if isinstance(pyobject, pyobjects.PyFunction) and \ isinstance(pyobject.parent, pyobjects.PyClass): return MoveMethod(project, resource, offset) if isinstance(pyobject, pyobjects.PyDefinedObject) and \ isinstance(pyobject.parent, pyobjects.PyModule): return MoveGlobal(project, resource, offset) raise exceptions.RefactoringError( 'Move only works on global classes/functions, modules and methods.')
def _check_exceptional_conditions(self): if self.old_pyname is None or \ not isinstance(self.old_pyname.get_object(), pyobjects.PyDefinedObject): raise exceptions.RefactoringError( 'Move refactoring should be performed on a class/function.') moving_pyobject = self.old_pyname.get_object() if not self._is_global(moving_pyobject): raise exceptions.RefactoringError( 'Move refactoring should be performed on a global class/function.')
def _check_returns(self): node = self.pyfunction.get_ast() if _yield_count(node): raise exceptions.RefactoringError( "Use function should not be used on generatorS.") returns = _return_count(node) if returns > 1: raise exceptions.RefactoringError( "usefunction: Function has more than one return statement.") if returns == 1 and not _returns_last(node): raise exceptions.RefactoringError( "usefunction: return should be the last statement.")
def __init__(self, project, resource, offset): self.project = project self.resource = resource self.offset = offset self.pymodule = self.project.get_pymodule(self.resource) scope = self.pymodule.get_scope().get_inner_scope_for_offset(offset) if scope.get_kind() != 'Function': raise exceptions.RefactoringError( 'Introduce parameter should be performed inside functions') self.pyfunction = scope.pyobject self.name, self.pyname = self._get_name_and_pyname() if self.pyname is None: raise exceptions.RefactoringError( 'Cannot find the definition of <%s>' % self.name)
def __init__(self, project, resource, offset): self.project = project self.offset = offset this_pymodule = project.pycore.resource_to_pyobject(resource) pyname = evaluate.eval_location(this_pymodule, offset) if pyname is None: raise exceptions.RefactoringError('Unresolvable name selected') self.pyfunction = pyname.get_object() if not isinstance(self.pyfunction, pyobjects.PyFunction) or \ not isinstance(self.pyfunction.parent, pyobjects.PyModule): raise exceptions.RefactoringError( 'Use function works for global functions, only.') self.resource = self.pyfunction.get_module().get_resource() self._check_returns()
def get_changed_module(self): result = [] for occurrence in self.finder.find_occurrences(self.resource, self.pymodule): start, end = occurrence.get_word_range() if self.skip_start <= start < self.skip_end: continue self._manage_writes(start, result) result.append(self.source[self.last_modified:start]) if self._is_assigned_in_a_tuple_assignment(occurrence): raise exceptions.RefactoringError( 'Cannot handle tuple assignments in encapsulate field.') if occurrence.is_written(): assignment_type = self.worder.get_assignment_type(start) if assignment_type == '=': result.append(self.setter + '(') else: var_name = self.source[occurrence.get_primary_range()[0]: start] + self.getter + '()' result.append(self.setter + '(' + var_name + ' %s ' % assignment_type[:-1]) current_line = self.lines.get_line_number(start) start_line, end_line = self.pymodule.logical_lines.\ logical_line_in(current_line) self.last_set = self.lines.get_line_end(end_line) end = self.source.index('=', end) + 1 self.set_index = len(result) else: result.append(self.getter + '()') self.last_modified = end if self.last_modified != 0: self._manage_writes(len(self.source), result) result.append(self.source[self.last_modified:]) return ''.join(result) return None
def __init__(self, project, resource, offset=None): """If `offset` is None, the `resource` itself will be renamed""" self.project = project self.pycore = project.pycore self.resource = resource if offset is not None: self.old_name = worder.get_name_at(self.resource, offset) this_pymodule = self.pycore.resource_to_pyobject(self.resource) self.old_instance, self.old_pyname = \ evaluate.eval_location2(this_pymodule, offset) if self.old_pyname is None: raise exceptions.RefactoringError( 'Rename refactoring should be performed' ' on resolvable python identifiers.') else: if not resource.is_folder() and resource.name == '__init__.py': resource = resource.parent dummy_pymodule = self.pycore.get_string_module('') self.old_instance = None self.old_pyname = pynames.ImportedModule(dummy_pymodule, resource=resource) if resource.is_folder(): self.old_name = resource.name else: self.old_name = resource.name[:-3]
def get_changes(self, dest, resources=None, task_handle=taskhandle.NullTaskHandle()): if resources is None: resources = self.project.get_python_files() if dest is None or not dest.exists(): raise exceptions.RefactoringError( 'Move destination does not exist.') if dest.is_folder() and dest.has_child('__init__.py'): dest = dest.get_child('__init__.py') if dest.is_folder(): raise exceptions.RefactoringError( 'Move destination for non-modules should not be folders.') if self.source == dest: raise exceptions.RefactoringError( 'Moving global elements to the same module.') return self._calculate_changes(dest, resources, task_handle)
def get_changes(self, dest, resources=None, task_handle=taskhandle.NullTaskHandle()): if resources is None: resources = self.project.get_python_files() if dest is None or not dest.is_folder(): raise exceptions.RefactoringError( 'Move destination for modules should be packages.') return self._calculate_changes(dest, resources, task_handle)
def get_package(self): primary = self.primary if self.primary is None: return self.pycore.project.get_source_folders()[0] if isinstance(primary.get_object(), pyobjects.PyPackage): return primary.get_object().get_resource() raise exceptions.RefactoringError( "A module/package can be only created in a package.")
def __init__(self, project, resource, offset): self.project = project this_pymodule = self.project.get_pymodule(resource) pyname = evaluate.eval_location(this_pymodule, offset) self.method_name = worder.get_name_at(resource, offset) self.pyfunction = pyname.get_object() if self.pyfunction.get_kind() != 'method': raise exceptions.RefactoringError('Only normal methods' ' can be moved.')
def __init__(self, project, resource, offset): self.pycore = project.pycore self.name = worder.get_name_at(resource, offset) this_pymodule = self.pycore.resource_to_pyobject(resource) self.pyname = evaluate.eval_location(this_pymodule, offset) if not self._is_an_attribute(self.pyname): raise exceptions.RefactoringError( 'Encapsulate field should be performed on class attributes.') self.resource = self.pyname.get_definition_location()[0].get_resource()
def _get_changes_made_by_new_class(self, dest_attr, new_name): old_pyclass = self.pyfunction.parent if dest_attr not in old_pyclass: raise exceptions.RefactoringError( 'Destination attribute <%s> not found' % dest_attr) pyclass = old_pyclass[dest_attr].get_object().get_type() if not isinstance(pyclass, pyobjects.PyClass): raise exceptions.RefactoringError( 'Unknown class type for attribute <%s>' % dest_attr) pymodule = pyclass.get_module() resource = pyclass.get_module().get_resource() start, end = sourceutils.get_body_region(pyclass) pre_blanks = '\n' if pymodule.source_code[start:end].strip() != 'pass': pre_blanks = '\n\n' start = end indents = self._get_scope_indents(pyclass) body = pre_blanks + sourceutils.fix_indentation( self.get_new_method(new_name), indents) return resource, start, end, body
def get_changes(self): package = self.info.get_package() changes = change.ChangeSet('Generate Module <%s>' % self.name) new_resource = self.project.get_file('%s/%s.py' % (package.path, self.name)) if new_resource.exists(): raise exceptions.RefactoringError( 'Module <%s> already exists' % new_resource.path) changes.add_change(change.CreateResource(new_resource)) changes.add_change(_add_import_to_module( self.project.pycore, self.resource, new_resource)) return changes
def __init__(self, project, resource, offset): self.pycore = project.pycore this_pymodule = self.pycore.resource_to_pyobject(resource) pyname = evaluate.eval_location(this_pymodule, offset) if pyname is None or not isinstance(pyname.get_object(), pyobjects.PyFunction): raise exceptions.RefactoringError( 'Replace method with method object refactoring should be ' 'performed on a function.') self.pyfunction = pyname.get_object() self.pymodule = self.pyfunction.get_module() self.resource = self.pymodule.get_resource()
def get_changes(self): package = self.info.get_package() changes = change.ChangeSet("Generate Package <%s>" % self.name) new_resource = self.project.get_folder("%s/%s" % (package.path, self.name)) if new_resource.exists(): raise exceptions.RefactoringError("Package <%s> already exists" % new_resource.path) changes.add_change(change.CreateResource(new_resource)) changes.add_change( _add_import_to_module(self.project, self.resource, new_resource)) child = self.project.get_folder(package.path + "/" + self.name) changes.add_change(change.CreateFile(child, "__init__.py")) return changes
def __init__(self, project, resource): self.project = project if not resource.is_folder() and resource.name == '__init__.py': resource = resource.parent if resource.is_folder() and not resource.has_child('__init__.py'): raise exceptions.RefactoringError( 'Cannot move non-package folder.') dummy_pymodule = libutils.get_string_module(self.project, '') self.old_pyname = pynames.ImportedModule(dummy_pymodule, resource=resource) self.source = self.old_pyname.get_object().get_resource() if self.source.is_folder(): self.old_name = self.source.name else: self.old_name = self.source.name[:-3] self.tools = _MoveTools(self.project, self.source, self.old_pyname, self.old_name) self.import_tools = self.tools.import_tools
def get_changes(self): name = worder.get_name_at(self.resource, self.offset) this_pymodule = self.project.get_pymodule(self.resource) pyname = evaluate.eval_location(this_pymodule, self.offset) if not self._is_a_method_local(pyname): raise exceptions.RefactoringError( 'Convert local variable to field should be performed on \n' 'a local variable of a method.') pymodule, lineno = pyname.get_definition_location() function_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) # Not checking redefinition #self._check_redefinition(name, function_scope) new_name = self._get_field_name(function_scope.pyobject, name) changes = Rename(self.project, self.resource, self.offset).\ get_changes(new_name, resources=[self.resource]) return changes
def __init__(self, project, resource, offset): self.project = project this_pymodule = self.project.get_pymodule(resource) self.old_pyname = evaluate.eval_location(this_pymodule, offset) if self.old_pyname is None: raise exceptions.RefactoringError( 'Move refactoring should be performed on a ' 'class/function/variable.') if self._is_variable(self.old_pyname): self.old_name = worder.get_name_at(resource, offset) pymodule = this_pymodule else: self.old_name = self.old_pyname.get_object().get_name() pymodule = self.old_pyname.get_object().get_module() self._check_exceptional_conditions() self.source = pymodule.get_resource() self.tools = _MoveTools(self.project, self.source, self.old_pyname, self.old_name) self.import_tools = self.tools.import_tools
def _raise_refactoring_error(self): raise exceptions.RefactoringError( 'Move refactoring should be performed on a global class, function ' 'or variable.')
def _check_redefinition(self, name, function_scope): class_scope = function_scope.parent if name in class_scope.pyobject: raise exceptions.RefactoringError( 'The field %s already exists' % name)