GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — pythonVSCode/pythonFiles/rope/refactor/rename.py at master · MightyWing/pythonVSCode Expand file tree/ Copy pathrename.pyMore file actions 220 lines (192 loc) · 9.16 KB / Copy pathrename.pyFile metadata and controls220 lines (192 loc) · 9.16 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 import warnings from rope.base import (exceptions, pyobjects, pynames, taskhandle, evaluate, worder, codeanalyze, libutils) from rope.base.change import ChangeSet, ChangeContents, MoveResource from rope.refactor import occurrences class Rename(object): """A class for performing rename refactoring It can rename everything: classes, functions, modules, packages, methods, variables and keyword arguments. """ def __init__(self, project, resource, offset=None): """If `offset` is None, the `resource` itself will be renamed""" self.project = project self.resource = resource if offset is not None: self.old_name = worder.get_name_at(self.resource, offset) this_pymodule = self.project.get_pymodule(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 = libutils.get_string_module(self.project, '') 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_old_name(self): return self.old_name 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.project.get_python_files() changes = ChangeSet('Renaming <%s> to <%s>' % (self.old_name, new_name)) finder = occurrences.create_finder( self.project, 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 _is_allowed_to_move(self, resources, resource): if resource.is_folder(): try: return resource.get_child('__init__.py') in resources except exceptions.ResourceNotFoundError: return False else: return resource in resources def _is_renaming_a_module(self): if isinstance(self.old_pyname.get_object(), pyobjects.AbstractModule): return True return False def is_method(self): pyname = self.old_pyname return isinstance(pyname, pynames.DefinedName) and \ isinstance(pyname.get_object(), pyobjects.PyFunction) and \ isinstance(pyname.get_object().parent, pyobjects.PyClass) def _rename_module(self, resource, new_name, changes): if not resource.is_folder(): new_name = new_name + '.py' parent_path = resource.parent.path if parent_path == '': new_location = new_name else: new_location = parent_path + '/' + new_name changes.add_change(MoveResource(resource, new_location)) class ChangeOccurrences(object): """A class for changing the occurrences of a name in a scope This class replaces the occurrences of a name. Note that it only changes the scope containing the offset passed to the constructor. What's more it does not have any side-effects. That is for example changing occurrences of a module does not rename the module; it merely replaces the occurrences of that module in a scope with the given expression. This class is useful for performing many custom refactorings. """ def __init__(self, project, resource, offset): self.project = project self.resource = resource self.offset = offset self.old_name = worder.get_name_at(resource, offset) self.pymodule = project.get_pymodule(self.resource) self.old_pyname = evaluate.eval_location(self.pymodule, offset) def get_old_name(self): word_finder = worder.Worder(self.resource.read()) return word_finder.get_primary_at(self.offset) def _get_scope_offset(self): lines = self.pymodule.lines scope = self.pymodule.get_scope().\ get_inner_scope_for_line(lines.get_line_number(self.offset)) start = lines.get_line_start(scope.get_start()) end = lines.get_line_end(scope.get_end()) return start, end 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.project, 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 rename_in_module(occurrences_finder, new_name, resource=None, pymodule=None, replace_primary=False, region=None, reads=True, writes=True): """Returns the changed source or `None` if there is no changes""" if resource is not None: source_code = resource.read() else: source_code = pymodule.source_code change_collector = codeanalyze.ChangeCollector(source_code) for occurrence in occurrences_finder.find_occurrences(resource, pymodule): if replace_primary and occurrence.is_a_fixed_primary(): continue if replace_primary: start, end = occurrence.get_primary_range() else: start, end = occurrence.get_word_range() if (not reads and not occurrence.is_written()) or \ (not writes and occurrence.is_written()): continue if region is None or region[0] <= start < region[1]: change_collector.add_change(start, end, new_name) return change_collector.get_changed() def _is_local(pyname): module, lineno = pyname.get_definition_location() if lineno is None: return False scope = module.get_scope().get_inner_scope_for_line(lineno) if isinstance(pyname, pynames.DefinedName) and \ scope.get_kind() in ('Function', 'Class'): scope = scope.parent return scope.get_kind() == 'Function' and \ pyname in scope.get_names().values() and \ isinstance(pyname, pynames.AssignedName) |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |