Lines Matching +full:m +full:- +full:class
7 # the COPYING file in the top-level directory.
28 class Patch(NamedTuple):
37 class RequiredIdentifier(NamedTuple):
41 class FileMatch:
42 """Base class for regex matches
44 Subclasses just need to set the `regexp` class attribute
48 def __init__(self, f: 'FileInfo', m: Match) -> None:
50 self.match: Match[str] = m
53 def name(self) -> str:
62 def start(self) -> int:
65 def end(self) -> int:
68 def line_col(self) -> LineAndColumn:
71 def group(self, group: Union[int, str]) -> str:
74 def getgroup(self, group: str) -> Optional[str]:
79 def log(self, level, fmt, *args) -> None:
83 def debug(self, fmt, *args) -> None:
86 def info(self, fmt, *args) -> None:
89 def warn(self, fmt, *args) -> None:
92 def error(self, fmt, *args) -> None:
95 def sub(self, original: str, replacement: str) -> str:
105 def sanity_check(self) -> None:
109 def replacement(self) -> Optional[str]:
113 def make_patch(self, replacement: str) -> 'Patch':
117 def make_subpatch(self, start: int, end: int, replacement: str) -> 'Patch':
120 def make_removal_patch(self) -> 'Patch':
124 def append(self, s: str) -> 'Patch':
128 def prepend(self, s: str) -> 'Patch':
132 def gen_patches(self) -> Iterable['Patch']:
139 def has_replacement_rule(klass) -> bool:
143 def contains(self, other: 'FileMatch') -> bool:
146 def __repr__(self) -> str:
148 end = self.file.line_col(self.end() - 1)
149 return '<%s %s at %d:%d-%d:%d: %r>' % (self.__class__.__name__,
154 def required_identifiers(self) -> Iterable[RequiredIdentifier]:
162 def provided_identifiers(self) -> Iterable[RequiredIdentifier]:
171 def finditer(klass, content: str, pos=0, endpos=-1) -> Iterable[Match]:
178 def domatch(klass, content: str, pos=0, endpos=-1) -> Optional[Match]:
184 …def group_finditer(self, klass: Type['FileMatch'], group: Union[str, int]) -> Iterable['FileMatch'…
186 return (klass(self.file, m)
187 for m in klass.finditer(self.file.original_content,
191 …def try_group_match(self, klass: Type['FileMatch'], group: Union[str, int]) -> Optional['FileMatch…
193 m = klass.domatch(self.file.original_content,
196 if not m:
199 return klass(self.file, m)
201 def group_match(self, group: Union[str, int]) -> 'FileMatch':
202 m = self.try_group_match(FullMatch, group)
203 assert m
204 return m
207 def allfiles(self) -> 'FileList':
210 class FullMatch(FileMatch):
216 def all_subclasses(c: Type[FileMatch]) -> Iterable[Type[FileMatch]]:
221 def match_class_dict() -> Dict[str, Type[FileMatch]]:
225 def names(matches: Iterable[FileMatch]) -> Iterable[str]:
226 return [m.name for m in matches]
228 class PatchingError(Exception):
231 class OverLappingPatchesError(PatchingError):
234 def apply_patches(s: str, patches: Iterable[Patch]) -> str:
242 def patch_sort_key(item: Tuple[int, Patch]) -> Tuple[int, int, int]:
251 DBG("Applying patch at position %d (%s) - %d (%s): %r",
264 class RegexpScanner:
265 def __init__(self) -> None:
269 def _matches_of_type(self, klass: Type[Any]) -> Iterable[FileMatch]:
272 def matches_of_type(self, t: Type[T]) -> List[T]:
277 def find_matches(self, t: Type[T], name: str, group: str='name') -> List[T]:
282 for m in self.matches_of_type(t):
283 assert isinstance(m, FileMatch)
284 if m.getgroup(group) == name:
285 r.append(m) # type: ignore
289 def find_match(self, t: Type[T], name: str, group: str='name') -> Optional[T]:
298 def reset_index(self) -> None:
302 class FileInfo(RegexpScanner):
306 def __init__(self, files: 'FileList', filename: os.PathLike, force:bool=False) -> None:
313 def __repr__(self) -> str:
316 def filename_matches(self, name: str) -> bool:
318 return self.filename.parts[-len(nameparts):] == nameparts
320 def line_col(self, start: int) -> LineAndColumn:
324 def _matches_of_type(self, klass: Type[Any]) -> List[FileMatch]:
331 matches = [klass(self, m) for m in klass.finditer(self.original_content)]
336 def find_match(self, t: Type[T], name: str, group: str='name') -> Optional[T]:
337 for m in self.matches_of_type(t):
338 assert isinstance(m, FileMatch)
339 if m.getgroup(group) == name:
340 return m # type: ignore
349 def load(self) -> None:
356 def all_matches(self) -> Iterable[FileMatch]:
358 return (m for l in lists
359 for m in l)
361 def gen_patches(self, matches: List[FileMatch]) -> None:
362 for m in matches:
363 DBG("Generating patches for %r", m)
364 for i,p in enumerate(m.gen_patches()):
365 DBG("patch %d generated by %r:", i, m)
366 DBG("replace contents at %s-%s with %r",
370 def scan_for_matches(self, class_names: Optional[List[str]]=None) -> Iterable[FileMatch]:
371 DBG("class names: %r", class_names)
374 DBG("default class names")
384 def apply_patches(self) -> None:
388 def get_patched_content(self) -> str:
392 def write_to_file(self, f: IO[str]) -> None:
395 def write_to_filename(self, filename: os.PathLike) -> None:
399 def patch_inplace(self) -> None:
404 def show_diff(self) -> None:
408 subprocess.call(['diff', '-u', self.filename, f.name])
413 class FileList(RegexpScanner):
424 def _matches_of_type(self, klass: Type[Any]) -> Iterable[FileMatch]:
427 def find_file(self, name: str) -> Optional[FileInfo]:
435 def one_pass(self, class_names: List[str]) -> int:
451 def patch_content(self, max_passes, class_names: List[str]) -> None:
452 """Multi-pass content patching loop