def get_changes(self, remove=True, only_current=False, resources=None, task_handle=taskhandle.NullTaskHandle()): """Get the changes this refactoring makes If `remove` is `False` the definition will not be removed. If `only_current` is `True`, the the current occurrence will be inlined, only. """ changes = ChangeSet('Inline method <%s>' % self.name) if resources is None: resources = self.pycore.get_python_files() if only_current: resources = [self.resource] job_set = task_handle.create_jobset('Collecting Changes', len(resources)) for file in resources: job_set.started_job(file.path) if file == self.resource: changes.add_change(self._defining_file_changes( changes, remove=remove, only_current=only_current)) else: handle = _InlineFunctionCallsForModuleHandle( self.pycore, file, self.others_generator) result = move.ModuleSkipRenamer( self.occurrence_finder, file, handle).get_changed_module() if result is not None: result = self._add_imports(result, file) changes.add_change(ChangeContents(file, result)) job_set.finished_job() return changes
def get_changes(self, remove=True, only_current=False, resources=None, task_handle=taskhandle.NullTaskHandle()): if resources is None: if rename._is_local(self.pyname): resources = [self.resource] else: resources = self.pycore.get_python_files() if only_current: resources = [self.original] if remove and self.original != self.resource: resources.append(self.resource) changes = ChangeSet('Inline variable <%s>' % self.name) jobset = task_handle.create_jobset('Calculating changes', len(resources)) for resource in resources: jobset.started_job(resource.path) if resource == self.resource: source = self._change_main_module(remove, only_current) changes.add_change(ChangeContents(self.resource, source)) else: result = self._change_module(resource, remove, only_current) if result is not None: result = _add_imports(self.pycore, result, resource, self.imports) changes.add_change(ChangeContents(resource, result)) jobset.finished_job() return changes
def _change_calls( self, call_changer, in_hierarchy=None, resources=None, handle=taskhandle.NullTaskHandle(), ): if resources is None: resources = self.project.get_python_files() changes = ChangeSet("Changing signature of <%s>" % self.name) job_set = handle.create_jobset("Collecting Changes", len(resources)) finder = occurrences.create_finder( self.project, self.name, self.pyname, instance=self.primary, in_hierarchy=in_hierarchy and self.is_method(), ) if self.others: name, pyname = self.others constructor_finder = occurrences.create_finder(self.project, name, pyname, only_calls=True) finder = _MultipleFinders([finder, constructor_finder]) for file in resources: job_set.started_job(file.path) change_calls = _ChangeCallsInModule(self.project, finder, file, call_changer) changed_file = change_calls.get_changed_module() if changed_file is not None: changes.add_change(ChangeContents(file, changed_file)) job_set.finished_job() return changes
def get_changes(self, remove=True, only_current=False, resources=None, task_handle=taskhandle.NullTaskHandle()): source = self._get_changed_module(remove, only_current) changes = ChangeSet('Inline variable <%s>' % self.name) if resources is None or self.resource in resources: changes.add_change(ChangeContents(self.resource, source)) return changes
def get_changes(self, new_name, in_file=None, in_hierarchy=False, unsure=None, docs=False, resources=None, task_handle=taskhandle.NullTaskHandle()): """Get the changes needed for this refactoring Parameters: - `in_hierarchy`: when renaming a method this keyword forces to rename all matching methods in the hierarchy - `docs`: when `True` rename refactoring will rename occurrences in comments and strings where the name is visible. Setting it will make renames faster, too. - `unsure`: decides what to do about unsure occurrences. If `None`, they are ignored. Otherwise `unsure` is called with an instance of `occurrence.Occurrence` as parameter. If it returns `True`, the occurrence is considered to be a match. - `resources` can be a list of `rope.base.resources.File`\s to apply this refactoring on. If `None`, the restructuring will be applied to all python files. - `in_file`: this argument has been deprecated; use `resources` instead. """ if unsure in (True, False): warnings.warn( 'unsure parameter should be a function that returns ' 'True or False', DeprecationWarning, stacklevel=2) def unsure_func(value=unsure): return value unsure = unsure_func if in_file is not None: warnings.warn( '`in_file` argument has been deprecated; use `resources` ' 'instead. ', DeprecationWarning, stacklevel=2) if in_file: resources = [self.resource] if _is_local(self.old_pyname): resources = [self.resource] if resources is None: resources = self.pycore.get_python_files() changes = ChangeSet('Renaming <%s> to <%s>' % (self.old_name, new_name)) finder = occurrences.create_finder( self.pycore, self.old_name, self.old_pyname, unsure=unsure, docs=docs, instance=self.old_instance, in_hierarchy=in_hierarchy and self.is_method()) job_set = task_handle.create_jobset('Collecting Changes', len(resources)) for file_ in resources: job_set.started_job(file_.path) new_content = rename_in_module(finder, new_name, resource=file_) if new_content is not None: changes.add_change(ChangeContents(file_, new_content)) job_set.finished_job() if self._is_renaming_a_module(): resource = self.old_pyname.get_object().get_resource() if self._is_allowed_to_move(resources, resource): self._rename_module(resource, new_name, changes) return changes
def _perform_command_on_import_tools(self, method, resource, offset): pymodule = self.project.get_pymodule(resource) before_performing = pymodule.source_code import_filter = None if offset is not None: import_filter = self._line_filter(pymodule.lines.get_line_number(offset)) result = method(pymodule, import_filter=import_filter) if result is not None and result != before_performing: changes = ChangeSet(method.__name__.replace("_", " ") + " in <%s>" % resource.path) changes.add_change(ChangeContents(resource, result)) return changes
def get_changes(self, new_name, only_calls=False, reads=True, writes=True): changes = ChangeSet('Changing <%s> occurrences to <%s>' % (self.old_name, new_name)) scope_start, scope_end = self._get_scope_offset() finder = occurrences.create_finder( self.pycore, self.old_name, self.old_pyname, imports=False, only_calls=only_calls) new_contents = rename_in_module( finder, new_name, pymodule=self.pymodule, replace_primary=True, region=(scope_start, scope_end), reads=reads, writes=writes) if new_contents is not None: changes.add_change(ChangeContents(self.resource, new_contents)) return changes
def _perform_command_on_import_tools(self, method, resource, offset): pymodule = self.project.get_pymodule(resource) before_performing = pymodule.source_code import_filter = None if offset is not None: import_filter = self._line_filter( pymodule.lines.get_line_number(offset)) result = method(pymodule, import_filter=import_filter) if result is not None and result != before_performing: changes = ChangeSet( method.__name__.replace("_", " ") + " in <%s>" % resource.path) changes.add_change(ChangeContents(resource, result)) return changes
def _calculate_changes(self, dest, resources, task_handle): changes = ChangeSet('Moving global <%s>' % self.old_name) job_set = task_handle.create_jobset('Collecting Changes', len(resources)) for file_ in resources: job_set.started_job(file_.path) if file_ == self.source: changes.add_change(self._source_module_changes(dest)) elif file_ == dest: changes.add_change(self._dest_module_changes(dest)) elif self.tools.occurs_in_module(resource=file_): pymodule = self.project.get_pymodule(file_) # Changing occurrences placeholder = '__rope_renaming_%s_' % self.old_name source = self.tools.rename_in_module(placeholder, resource=file_) should_import = source is not None # Removing out of date imports pymodule = self.tools.new_pymodule(pymodule, source) source = self.tools.remove_old_imports(pymodule) # Adding new import if should_import: pymodule = self.tools.new_pymodule(pymodule, source) source, imported = importutils.add_import( self.project, pymodule, self._new_modname(dest), self.old_name) source = source.replace(placeholder, imported) source = self.tools.new_source(pymodule, source) if source != file_.read(): changes.add_change(ChangeContents(file_, source)) job_set.finished_job() return changes
def _calculate_changes(self, dest, resources, task_handle): changes = ChangeSet("Moving module <%s>" % self.old_name) job_set = task_handle.create_jobset("Collecting changes", len(resources)) for module in resources: job_set.started_job(module.path) if module == self.source: self._change_moving_module(changes, dest) else: source = self._change_occurrences_in_module(dest, resource=module) if source is not None: changes.add_change(ChangeContents(module, source)) job_set.finished_job() if self.project == self.source.project: changes.add_change(MoveResource(self.source, dest.path)) return changes
def get_changes( self, factory_name, global_factory=False, resources=None, task_handle=taskhandle.NullTaskHandle(), ): """Get the changes this refactoring makes `factory_name` indicates the name of the factory function to be added. If `global_factory` is `True` the factory will be global otherwise a static method is added to the class. `resources` can be a list of `rope.base.resource.File` that this refactoring should be applied on; if `None` all python files in the project are searched. """ if resources is None: resources = self.project.get_python_files() changes = ChangeSet("Introduce factory method <%s>" % factory_name) job_set = task_handle.create_jobset("Collecting Changes", len(resources)) self._change_module(resources, changes, factory_name, global_factory, job_set) return changes
def get_changes(self, dest_attr, new_name=None, resources=None, task_handle=taskhandle.NullTaskHandle()): """Return the changes needed for this refactoring Parameters: - `dest_attr`: the name of the destination attribute - `new_name`: the name of the new method; if `None` uses the old name - `resources` can be a list of `rope.base.resources.File`\s to apply this refactoring on. If `None`, the restructuring will be applied to all python files. """ changes = ChangeSet('Moving method <%s>' % self.method_name) if resources is None: resources = self.project.get_python_files() if new_name is None: new_name = self.get_method_name() resource1, start1, end1, new_content1 = \ self._get_changes_made_by_old_class(dest_attr, new_name) collector1 = codeanalyze.ChangeCollector(resource1.read()) collector1.add_change(start1, end1, new_content1) resource2, start2, end2, new_content2 = \ self._get_changes_made_by_new_class(dest_attr, new_name) if resource1 == resource2: collector1.add_change(start2, end2, new_content2) else: collector2 = codeanalyze.ChangeCollector(resource2.read()) collector2.add_change(start2, end2, new_content2) result = collector2.get_changed() import_tools = importutils.ImportTools(self.project) new_imports = self._get_used_imports(import_tools) if new_imports: goal_pymodule = libutils.get_string_module( self.project, result, resource2) result = _add_imports_to_module( import_tools, goal_pymodule, new_imports) if resource2 in resources: changes.add_change(ChangeContents(resource2, result)) if resource1 in resources: changes.add_change(ChangeContents(resource1, collector1.get_changed())) return changes
def _calculate_changes(self, dest, resources, task_handle): changes = ChangeSet("Moving global <%s>" % self.old_name) job_set = task_handle.create_jobset("Collecting Changes", len(resources)) for file_ in resources: job_set.started_job(file_.path) if file_ == self.source: changes.add_change(self._source_module_changes(dest)) elif file_ == dest: changes.add_change(self._dest_module_changes(dest)) elif self.tools.occurs_in_module(resource=file_): pymodule = self.project.get_pymodule(file_) # Changing occurrences placeholder = "__rope_renaming_%s_" % self.old_name source = self.tools.rename_in_module(placeholder, resource=file_) should_import = source is not None # Removing out of date imports pymodule = self.tools.new_pymodule(pymodule, source) source = self.import_tools.organize_imports(pymodule, sort=False, import_filter=self._import_filter) # Adding new import if should_import: pymodule = self.tools.new_pymodule(pymodule, source) source, imported = importutils.add_import( self.project, pymodule, self._new_modname(dest), self.old_name ) source = source.replace(placeholder, imported) source = self.tools.new_source(pymodule, source) if source != file_.read(): changes.add_change(ChangeContents(file_, source)) job_set.finished_job() return changes
def get_changes(self, extracted_name, similar=False, global_=False): """Get the changes this refactoring makes :parameters: - `similar`: if `True`, similar expressions/statements are also replaced. - `global_`: if `True`, the extracted method/variable will be global. """ info = _ExtractInfo( self.project, self.resource, self.start_offset, self.end_offset, extracted_name, variable=self.kind == 'variable', similar=similar, make_global=global_) new_contents = _ExtractPerformer(info).extract() changes = ChangeSet('Extract %s <%s>' % (self.kind, extracted_name)) changes.add_change(ChangeContents(self.resource, new_contents)) return changes
def get_changes(self, remove=True, only_current=False, resources=None, docs=False, task_handle=taskhandle.NullTaskHandle()): if resources is None: if rename._is_local(self.pyname): resources = [self.resource] else: resources = self.project.get_python_files() if only_current: resources = [self.original] if remove and self.original != self.resource: resources.append(self.resource) changes = ChangeSet('Inline variable <%s>' % self.name) jobset = task_handle.create_jobset('Calculating changes', len(resources)) for resource in resources: jobset.started_job(resource.path) if resource == self.resource: source = self._change_main_module(remove, only_current, docs) changes.add_change(ChangeContents(self.resource, source)) else: result = self._change_module(resource, remove, only_current) if result is not None: result = _add_imports(self.project, result, resource, self.imports) changes.add_change(ChangeContents(resource, result)) jobset.finished_job() return changes
def get_changes(self): changes = ChangeSet('Transform <%s> module to package' % self.resource.path) new_content = self._transform_relatives_to_absolute(self.resource) if new_content is not None: changes.add_change(ChangeContents(self.resource, new_content)) parent = self.resource.parent name = self.resource.name[:-3] changes.add_change(CreateFolder(parent, name)) parent_path = parent.path + '/' if not parent.path: parent_path = '' new_path = parent_path + '%s/__init__.py' % name if self.resource.project == self.project: changes.add_change(MoveResource(self.resource, new_path)) return changes
def _change_calls(self, call_changer, in_hierarchy=None, resources=None, handle=taskhandle.NullTaskHandle()): if resources is None: resources = self.project.get_python_files() changes = ChangeSet('Changing signature of <%s>' % self.name) job_set = handle.create_jobset('Collecting Changes', len(resources)) finder = occurrences.create_finder( self.project, self.name, self.pyname, instance=self.primary, in_hierarchy=in_hierarchy and self.is_method()) if self.others: name, pyname = self.others constructor_finder = occurrences.create_finder( self.project, name, pyname, only_calls=True) finder = _MultipleFinders([finder, constructor_finder]) for file in resources: job_set.started_job(file.path) change_calls = _ChangeCallsInModule( self.project, finder, file, call_changer) changed_file = change_calls.get_changed_module() if changed_file is not None: changes.add_change(ChangeContents(file, changed_file)) job_set.finished_job() return changes
def get_changes(self, getter=None, setter=None, resources=None, task_handle=taskhandle.NullTaskHandle()): """Get the changes this refactoring makes If `getter` is not `None`, that will be the name of the getter, otherwise ``get_${field_name}`` will be used. The same is true for `setter` and if it is None set_${field_name} is used. `resources` can be a list of `rope.base.resource.File`\s that the refactoring should be applied on; if `None` all python files in the project are searched. """ if resources is None: resources = self.pycore.get_python_files() changes = ChangeSet('Encapsulate field <%s>' % self.name) job_set = task_handle.create_jobset('Collecting Changes', len(resources)) if getter is None: getter = 'get_' + self.name if setter is None: setter = 'set_' + self.name renamer = GetterSetterRenameInModule( self.pycore, self.name, self.pyname, getter, setter) for file in resources: job_set.started_job(file.path) if file == self.resource: result = self._change_holding_module(changes, renamer, getter, setter) changes.add_change(ChangeContents(self.resource, result)) else: result = renamer.get_changed_module(file) if result is not None: changes.add_change(ChangeContents(file, result)) job_set.finished_job() return changes
def get_changes( self, dest_attr, new_name=None, resources=None, task_handle=taskhandle.NullTaskHandle(), ): """Return the changes needed for this refactoring Parameters: - `dest_attr`: the name of the destination attribute - `new_name`: the name of the new method; if `None` uses the old name - `resources` can be a list of `rope.base.resources.File` to apply this refactoring on. If `None`, the restructuring will be applied to all python files. """ changes = ChangeSet("Moving method <%s>" % self.method_name) if resources is None: resources = self.project.get_python_files() if new_name is None: new_name = self.get_method_name() resource1, start1, end1, new_content1 = self._get_changes_made_by_old_class( dest_attr, new_name) collector1 = codeanalyze.ChangeCollector(resource1.read()) collector1.add_change(start1, end1, new_content1) resource2, start2, end2, new_content2 = self._get_changes_made_by_new_class( dest_attr, new_name) if resource1 == resource2: collector1.add_change(start2, end2, new_content2) else: collector2 = codeanalyze.ChangeCollector(resource2.read()) collector2.add_change(start2, end2, new_content2) result = collector2.get_changed() import_tools = importutils.ImportTools(self.project) new_imports = self._get_used_imports(import_tools) if new_imports: goal_pymodule = libutils.get_string_module( self.project, result, resource2) result = _add_imports_to_module(import_tools, goal_pymodule, new_imports) if resource2 in resources: changes.add_change(ChangeContents(resource2, result)) if resource1 in resources: changes.add_change( ChangeContents(resource1, collector1.get_changed())) return changes
def _calculate_changes(self, dest, resources, task_handle): changes = ChangeSet('Moving module <%s>' % self.old_name) job_set = task_handle.create_jobset('Collecting changes', len(resources)) for module in resources: job_set.started_job(module.path) if module == self.source: self._change_moving_module(changes, dest) else: source = self._change_occurrences_in_module(dest, resource=module) if source is not None: changes.add_change(ChangeContents(module, source)) job_set.finished_job() if self.project == self.source.project: changes.add_change(MoveResource(self.source, dest.path)) return changes
def get_changes(self, remove=True, only_current=False, resources=None, task_handle=taskhandle.NullTaskHandle()): """Get the changes this refactoring makes If `remove` is `False` the definition will not be removed. If `only_current` is `True`, the the current occurrence will be inlined, only. """ changes = ChangeSet('Inline method <%s>' % self.name) if resources is None: resources = self.project.get_python_files() if only_current: resources = [self.original] if remove: resources.append(self.resource) job_set = task_handle.create_jobset('Collecting Changes', len(resources)) for file in resources: job_set.started_job(file.path) if file == self.resource: changes.add_change( self._defining_file_changes(changes, remove=remove, only_current=only_current)) else: aim = None if only_current and self.original == file: aim = self.offset handle = _InlineFunctionCallsForModuleHandle( self.project, file, self.others_generator, aim) result = move.ModuleSkipRenamer(self.occurrence_finder, file, handle).get_changed_module() if result is not None: result = _add_imports(self.project, result, file, self.imports) if remove: result = _remove_from(self.project, self.pyname, result, file) changes.add_change(ChangeContents(file, result)) job_set.finished_job() return changes
def get_changes(self, getter=None, setter=None, resources=None, task_handle=taskhandle.NullTaskHandle()): """Get the changes this refactoring makes If `getter` is not `None`, that will be the name of the getter, otherwise ``get_${field_name}`` will be used. The same is true for `setter` and if it is None set_${field_name} is used. `resources` can be a list of `rope.base.resource.File`\s that the refactoring should be applied on; if `None` all python files in the project are searched. """ if resources is None: resources = self.project.get_python_files() changes = ChangeSet('Encapsulate field <%s>' % self.name) job_set = task_handle.create_jobset('Collecting Changes', len(resources)) if getter is None: getter = 'get_' + self.name if setter is None: setter = 'set_' + self.name renamer = GetterSetterRenameInModule(self.project, self.name, self.pyname, getter, setter) for file in resources: job_set.started_job(file.path) if file == self.resource: result = self._change_holding_module(changes, renamer, getter, setter) changes.add_change(ChangeContents(self.resource, result)) else: result = renamer.get_changed_module(file) if result is not None: changes.add_change(ChangeContents(file, result)) job_set.finished_job() return changes