Skip to content

Commit b7e4546

Browse files
committed
Enhance PythonParser with type hint checks and improve intra-file dependency resolution
1 parent c57ca57 commit b7e4546

1 file changed

Lines changed: 63 additions & 7 deletions

File tree

codetide/parsers/python_parser.py

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
CodeFileModel, MethodDefinition, Parameter, VariableDeclaration
77
)
88

9-
from typing import List, Literal, Optional, Union
9+
from typing import Any, List, Literal, Optional, Union
1010
from concurrent.futures import ThreadPoolExecutor
1111
from tree_sitter import Language, Parser, Node
1212
import tree_sitter_python as tspython
@@ -118,7 +118,7 @@ async def parse_file(self, file_path: Union[str, Path], root_path: Optional[Unio
118118
return codeFile
119119

120120
@classmethod
121-
def _process_node(cls, node: Node, code: bytes, codeFile :CodeFileModel):
121+
def _process_node(cls, node: Node, code: bytes, codeFile :CodeFileModel):
122122
for child in node.children:
123123
if child.type.startswith("import"):
124124
cls._process_import_node(child, code, codeFile)
@@ -469,6 +469,7 @@ def count_occurences_in_code(code: str, substring: str) -> int:
469469
return len(matches)
470470

471471
def resolve_intra_file_dependencies(self, codeBase: CodeBase) -> None:
472+
codeBase._build_cached_elements()
472473
for codeFile in codeBase.root:
473474
if not codeFile.file_path.endswith(self.extension):
474475
continue
@@ -490,7 +491,8 @@ def resolve_intra_file_dependencies(self, codeBase: CodeBase) -> None:
490491
matches_count=importCounts,
491492
codeFile=codeFile,
492493
unique_id=importStatement.unique_id,
493-
reference_name=importAsDependency
494+
reference_name=importAsDependency,
495+
imported_element=codeBase._cached_elements.get(importStatement.unique_id)
494496
)
495497

496498
for elemen_type in ["variables", "functions", "classes"]:
@@ -563,13 +565,38 @@ def _get_element_count(cls, raw_contents :List[str], element):
563565
return elementCounts
564566

565567
@staticmethod
568+
def _check_for_typehint_class_methods_attr_references(
569+
imported_element :Union[ClassDefinition, Any],
570+
element_to_check :Union[VariableDeclaration, FunctionDefinition, ClassAttribute, ClassDefinition],
571+
ref_type :str="type_hint")->bool:
572+
573+
if not isinstance(imported_element, ClassDefinition):
574+
return False
575+
576+
reference_found = False
577+
for imported_element_method in imported_element.methods:
578+
if imported_element_method.name in element_to_check.raw:
579+
element_to_check.references.append(
580+
CodeReference(
581+
unique_id=imported_element_method.unique_id,
582+
name=imported_element_method.name,
583+
type=ref_type
584+
)
585+
)
586+
reference_found = True
587+
588+
return reference_found
589+
590+
@classmethod
566591
def _find_references(
592+
cls,
567593
non_import_ids :List[str],
568594
raw_contents :List[str],
569595
matches_count :int,
570596
codeFile :CodeFileModel,
571597
unique_id :str,
572-
reference_name :str):
598+
reference_name :str,
599+
imported_element :Optional[Union[ClassDefinition, VariableDeclaration, FunctionDefinition]]=None):
573600

574601
matches_found = 0
575602
for _id, raw_content in zip(non_import_ids, raw_contents):
@@ -579,50 +606,79 @@ def _find_references(
579606
### TODO check why getting counts occurence in codeElement.raw is resulting in misfilling
580607
counts = 1 #self.count_occurences_in_code(codeElement.raw, reference_name)
581608
if isinstance(codeElement, (VariableDeclaration, FunctionDefinition)):
609+
matches_found += counts
582610
if isinstance(codeElement, FunctionDefinition) and reference_name in codeElement.signature.type_hints:
583611
ref_type = "type_hint"
612+
584613
elif isinstance(codeElement, VariableDeclaration) and reference_name == codeElement.type_hint:
585614
ref_type = "type_hint"
586615

616+
if cls._check_for_typehint_class_methods_attr_references(
617+
imported_element=imported_element,
618+
element_to_check=codeElement,
619+
ref_type=ref_type
620+
):
621+
continue
622+
587623
codeElement.references.append(
588624
CodeReference(
589625
unique_id=unique_id,
590626
name=reference_name,
591627
type=ref_type
592628
)
593629
)
594-
matches_found += counts
595630

596631
elif isinstance(codeElement, (ClassDefinition)):
597632
for method in codeElement.methods:
598633
ref_type = None
634+
matches_found += counts
599635
if reference_name in method.raw:
636+
600637
if reference_name in method.signature.type_hints:
601638
ref_type = "type_hint"
639+
640+
if cls._check_for_typehint_class_methods_attr_references(
641+
imported_element=imported_element,
642+
element_to_check=method,
643+
ref_type=ref_type
644+
):
645+
if matches_found >= matches_count:
646+
break
647+
continue
648+
602649
method.references.append(
603650
CodeReference(
604651
unique_id=unique_id,
605652
name=reference_name,
606653
type=ref_type
607654
)
608655
)
609-
matches_found += counts
610656
if matches_found >= matches_count:
611657
break
612658

613659
for attribute in codeElement.attributes:
614660
ref_type = None
615661
if reference_name in attribute.raw:
662+
matches_found += counts
616663
if reference_name == attribute.type_hint:
617664
ref_type = "type_hint"
665+
666+
if cls._check_for_typehint_class_methods_attr_references(
667+
imported_element=imported_element,
668+
element_to_check=method,
669+
ref_type=ref_type
670+
):
671+
if matches_found >= matches_count:
672+
break
673+
continue
674+
618675
attribute.references.append(
619676
CodeReference(
620677
unique_id=unique_id,
621678
name=reference_name,
622679
type=ref_type
623680
)
624681
)
625-
matches_found += counts
626682
if matches_found >= matches_count:
627683
break
628684

0 commit comments

Comments
 (0)