2222from codegen .shared .decorators .docs import apidoc , noapidoc
2323
2424if TYPE_CHECKING :
25- from collections .abc import Callable , Generator , Iterable
25+ from collections .abc import Callable , Generator , Iterable , Sequence
2626
2727 import rich .repr
2828 from rich .console import Console , ConsoleOptions , RenderResult
@@ -157,7 +157,7 @@ def __repr__(self) -> str:
157157 def __rich_repr__ (self ) -> rich .repr .Result :
158158 yield escape (self .filepath )
159159
160- __rich_repr__ .angular = ANGULAR_STYLE
160+ __rich_repr__ .angular = ANGULAR_STYLE # type: ignore
161161
162162 def __rich_console__ (self , console : Console , options : ConsoleOptions ) -> RenderResult :
163163 yield Pretty (self , max_string = MAX_STRING_LENGTH )
@@ -315,14 +315,14 @@ def extended_source(self, value: str) -> None:
315315 @property
316316 @reader
317317 @noapidoc
318- def children (self ) -> list [Editable ]:
318+ def children (self ) -> list [Editable [ Self ] ]:
319319 """List of Editable instances that are children of this node."""
320320 return [self ._parse_expression (child ) for child in self .ts_node .named_children ]
321321
322322 @property
323323 @reader
324324 @noapidoc
325- def _anonymous_children (self ) -> list [Editable ]:
325+ def _anonymous_children (self ) -> list [Editable [ Self ] ]:
326326 """All anonymous children of an editable."""
327327 return [self ._parse_expression (child ) for child in self .ts_node .children if not child .is_named ]
328328
@@ -343,28 +343,28 @@ def next_sibling(self) -> Editable | None:
343343 @property
344344 @reader
345345 @noapidoc
346- def next_named_sibling (self ) -> Editable | None :
346+ def next_named_sibling (self ) -> Editable [ Parent ] | None :
347347 if self .ts_node is None :
348348 return None
349349
350350 next_named_sibling_node = self .ts_node .next_named_sibling
351351 if next_named_sibling_node is None :
352352 return None
353353
354- return self ._parse_expression (next_named_sibling_node )
354+ return self .parent . _parse_expression (next_named_sibling_node )
355355
356356 @property
357357 @reader
358358 @noapidoc
359- def previous_named_sibling (self ) -> Editable | None :
359+ def previous_named_sibling (self ) -> Editable [ Parent ] | None :
360360 if self .ts_node is None :
361361 return None
362362
363363 previous_named_sibling_node = self .ts_node .prev_named_sibling
364364 if previous_named_sibling_node is None :
365365 return None
366366
367- return self ._parse_expression (previous_named_sibling_node )
367+ return self .parent . _parse_expression (previous_named_sibling_node )
368368
369369 @property
370370 def file (self ) -> SourceFile :
@@ -377,7 +377,7 @@ def file(self) -> SourceFile:
377377 """
378378 if self ._file is None :
379379 self ._file = self .G .get_node (self .file_node_id )
380- return self ._file
380+ return self ._file # type: ignore
381381
382382 @property
383383 def filepath (self ) -> str :
@@ -391,7 +391,7 @@ def filepath(self) -> str:
391391 return self .file .file_path
392392
393393 @reader
394- def find_string_literals (self , strings_to_match : list [str ], fuzzy_match : bool = False ) -> list [Editable ]:
394+ def find_string_literals (self , strings_to_match : list [str ], fuzzy_match : bool = False ) -> list [Editable [ Self ] ]:
395395 """Returns a list of string literals within this node's source that match any of the given
396396 strings.
397397
@@ -400,19 +400,20 @@ def find_string_literals(self, strings_to_match: list[str], fuzzy_match: bool =
400400 fuzzy_match (bool): If True, matches substrings within string literals. If False, only matches exact strings. Defaults to False.
401401
402402 Returns:
403- list[Editable]: A list of Editable objects representing the matching string literals.
403+ list[Editable[Self] ]: A list of Editable objects representing the matching string literals.
404404 """
405- matches = []
405+ matches : list [ Editable [ Self ]] = []
406406 for node in self .extended_nodes :
407407 matches .extend (node ._find_string_literals (strings_to_match , fuzzy_match ))
408408 return matches
409409
410410 @noapidoc
411411 @reader
412- def _find_string_literals (self , strings_to_match : list [str ], fuzzy_match : bool = False ) -> list [Editable ]:
412+ def _find_string_literals (self , strings_to_match : list [str ], fuzzy_match : bool = False ) -> Sequence [Editable [ Self ] ]:
413413 all_string_nodes = find_all_descendants (self .ts_node , type_names = {"string" })
414414 editables = []
415415 for string_node in all_string_nodes :
416+ assert string_node .text is not None
416417 full_string = string_node .text .strip (b'"' ).strip (b"'" )
417418 if fuzzy_match :
418419 if not any ([str_to_match .encode ("utf-8" ) in full_string for str_to_match in strings_to_match ]):
@@ -461,7 +462,7 @@ def _replace(self, old: str, new: str, count: int = -1, is_regex: bool = False,
461462 if not is_regex :
462463 old = re .escape (old )
463464
464- for match in re .finditer (old .encode ("utf-8" ), self .ts_node .text ):
465+ for match in re .finditer (old .encode ("utf-8" ), self .ts_node .text ): # type: ignore
465466 start_byte = self .ts_node .start_byte + match .start ()
466467 end_byte = self .ts_node .start_byte + match .end ()
467468 t = EditTransaction (
@@ -538,7 +539,7 @@ def _search(self, regex_pattern: str, include_strings: bool = True, include_comm
538539
539540 pattern = re .compile (regex_pattern .encode ("utf-8" ))
540541 start_byte_offset = self .ts_node .byte_range [0 ]
541- for match in pattern .finditer (string ):
542+ for match in pattern .finditer (string ): # type: ignore
542543 matching_byte_ranges .append ((match .start () + start_byte_offset , match .end () + start_byte_offset ))
543544
544545 matches : list [Editable ] = []
@@ -738,7 +739,7 @@ def should_keep(node: TSNode):
738739 # Delete the node
739740 t = RemoveTransaction (removed_start_byte , removed_end_byte , self .file , priority = priority , exec_func = exec_func )
740741 if self .transaction_manager .add_transaction (t , dedupe = dedupe ):
741- if exec_func :
742+ if exec_func is not None :
742743 self .parent ._removed_child ()
743744
744745 # If there are sibling nodes, delete the surrounding whitespace & formatting (commas)
@@ -873,11 +874,13 @@ def variable_usages(self) -> list[Editable]:
873874 Editable corresponds to a TreeSitter node instance where the variable
874875 is referenced.
875876 """
876- usages = []
877+ usages : Sequence [ Editable [ Self ]] = []
877878 identifiers = get_all_identifiers (self .ts_node )
878879 for identifier in identifiers :
879880 # Excludes function names
880881 parent = identifier .parent
882+ if parent is None :
883+ continue
881884 if parent .type in ["call" , "call_expression" ]:
882885 continue
883886 # Excludes local import statements
@@ -899,7 +902,7 @@ def variable_usages(self) -> list[Editable]:
899902 return usages
900903
901904 @reader
902- def get_variable_usages (self , var_name : str , fuzzy_match : bool = False ) -> list [Editable ]:
905+ def get_variable_usages (self , var_name : str , fuzzy_match : bool = False ) -> Sequence [Editable [ Self ] ]:
903906 """Returns Editables for all TreeSitter nodes corresponding to instances of variable usage
904907 that matches the given variable name.
905908
@@ -917,6 +920,12 @@ def get_variable_usages(self, var_name: str, fuzzy_match: bool = False) -> list[
917920 else :
918921 return [usage for usage in self .variable_usages if var_name == usage .source ]
919922
923+ @overload
924+ def _parse_expression (self , node : TSNode , ** kwargs ) -> Expression [Self ]: ...
925+
926+ @overload
927+ def _parse_expression (self , node : TSNode | None , ** kwargs ) -> Expression [Self ] | None : ...
928+
920929 def _parse_expression (self , node : TSNode | None , ** kwargs ) -> Expression [Self ] | None :
921930 return self .G .parser .parse_expression (node , self .file_node_id , self .G , self , ** kwargs )
922931
0 commit comments