diff --git a/src/py_to_uxf_core/abc/implementation_scanner_abc.py b/src/py_to_uxf_core/abc/implementation_scanner_abc.py index 0f0c213..e086cb0 100644 --- a/src/py_to_uxf_core/abc/implementation_scanner_abc.py +++ b/src/py_to_uxf_core/abc/implementation_scanner_abc.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod -from typing import Optional +from typing import Optional, Union + +from cpl_query.extension import List from py_to_uxf_core.model.class_implementation import ClassImplementation from py_to_uxf_core.model.python_class import PythonClass @@ -11,4 +13,4 @@ class ImplementationScannerABC(ABC): def __init__(self): pass @abstractmethod - def scan_line_for_implementation(self, line: str, classes: list[PythonClass]) -> Optional[ClassImplementation]: pass + def scan_line_for_implementation(self, line: str, classes: list[PythonClass]) -> Union[Optional[ClassImplementation], List[ClassImplementation]]: pass diff --git a/src/py_to_uxf_core/service/implementation_scanner_service.py b/src/py_to_uxf_core/service/implementation_scanner_service.py index 785fd28..6570563 100644 --- a/src/py_to_uxf_core/service/implementation_scanner_service.py +++ b/src/py_to_uxf_core/service/implementation_scanner_service.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Union from cpl_core.configuration import ConfigurationABC from cpl_core.console import Console @@ -16,7 +16,19 @@ class ImplementationScannerService(ImplementationScannerABC): ImplementationScannerABC.__init__(self) self._parser_settings: ParserSettings = configuration.get_configuration(ParserSettings) - def scan_line_for_implementation(self, line: str, classes: List[PythonClass]) -> Optional[ClassImplementation]: + def _get_implementation(self, base_name: str, sub_class: PythonClass, classes: List[PythonClass]) -> Optional[ClassImplementation]: + base: Optional[PythonClass] = classes.where(lambda c: c.name == base_name).first_or_default() + if base_name in self._parser_settings.ignore_class_names: + return None + + if base is None: + new_base = PythonClass(base_name) + classes.append(new_base) + return ClassImplementation(new_base, sub_class) + + return ClassImplementation(base, sub_class) + + def scan_line_for_implementation(self, line: str, classes: List[PythonClass]) -> Union[Optional[ClassImplementation], List[ClassImplementation]]: line = line.replace(' ', '') line = line.replace('\t', '') if line.startswith('class ') and '(' in line and ')' in line: @@ -25,15 +37,17 @@ class ImplementationScannerService(ImplementationScannerABC): if sub is None: return None + line = line.replace(' ', '') base_name = line.split('(')[1].split(')')[0] - base: Optional[PythonClass] = classes.where(lambda c: c.name == base_name).first_or_default() - if base_name in self._parser_settings.ignore_class_names: - return None + if ',' in base_name: + implementations = List(ClassImplementation) + for name in base_name.split(','): + if '=' in name: + continue - if base is None: - new_base = PythonClass(base_name) - classes.append(new_base) - return ClassImplementation(new_base, sub) - - return ClassImplementation(base, sub) + implementation = self._get_implementation(name, sub, classes) + if implementation is not None: + implementations.append(implementation) + return implementations + return self._get_implementation(base_name, sub, classes) return None diff --git a/src/py_to_uxf_core/service/python_parser_service.py b/src/py_to_uxf_core/service/python_parser_service.py index 6ca671a..ea38cfc 100644 --- a/src/py_to_uxf_core/service/python_parser_service.py +++ b/src/py_to_uxf_core/service/python_parser_service.py @@ -141,7 +141,11 @@ class PythonParserService(PythonParserABC): if implementation is None: implementation = self._implementation_scanner.scan_line_for_implementation(line, classes) if implementation is not None: - implementations.append(implementation) + if isinstance(implementation, List): + for impl in implementation: + implementations.append(impl) + else: + implementations.append(implementation) except Exception as e: Console.error(f'Parsing {file}@{i}', f'{e} -> {traceback.format_exc()}') file_content.close()