Added support for multiple base classes

This commit is contained in:
Sven Heidemann 2022-01-18 19:02:25 +01:00
parent 5aad932c7c
commit 1eb7aa37d3
3 changed files with 34 additions and 14 deletions

View File

@ -1,5 +1,7 @@
from abc import ABC, abstractmethod 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.class_implementation import ClassImplementation
from py_to_uxf_core.model.python_class import PythonClass from py_to_uxf_core.model.python_class import PythonClass
@ -11,4 +13,4 @@ class ImplementationScannerABC(ABC):
def __init__(self): pass def __init__(self): pass
@abstractmethod @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

View File

@ -1,4 +1,4 @@
from typing import Optional from typing import Optional, Union
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console from cpl_core.console import Console
@ -16,7 +16,19 @@ class ImplementationScannerService(ImplementationScannerABC):
ImplementationScannerABC.__init__(self) ImplementationScannerABC.__init__(self)
self._parser_settings: ParserSettings = configuration.get_configuration(ParserSettings) 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(' ', '')
line = line.replace('\t', '') line = line.replace('\t', '')
if line.startswith('class ') and '(' in line and ')' in line: if line.startswith('class ') and '(' in line and ')' in line:
@ -25,15 +37,17 @@ class ImplementationScannerService(ImplementationScannerABC):
if sub is None: if sub is None:
return None return None
line = line.replace(' ', '')
base_name = line.split('(')[1].split(')')[0] base_name = line.split('(')[1].split(')')[0]
base: Optional[PythonClass] = classes.where(lambda c: c.name == base_name).first_or_default() if ',' in base_name:
if base_name in self._parser_settings.ignore_class_names: implementations = List(ClassImplementation)
return None for name in base_name.split(','):
if '=' in name:
continue
if base is None: implementation = self._get_implementation(name, sub, classes)
new_base = PythonClass(base_name) if implementation is not None:
classes.append(new_base) implementations.append(implementation)
return ClassImplementation(new_base, sub) return implementations
return self._get_implementation(base_name, sub, classes)
return ClassImplementation(base, sub)
return None return None

View File

@ -141,6 +141,10 @@ class PythonParserService(PythonParserABC):
if implementation is None: if implementation is None:
implementation = self._implementation_scanner.scan_line_for_implementation(line, classes) implementation = self._implementation_scanner.scan_line_for_implementation(line, classes)
if implementation is not None: if implementation is not None:
if isinstance(implementation, List):
for impl in implementation:
implementations.append(impl)
else:
implementations.append(implementation) implementations.append(implementation)
except Exception as e: except Exception as e:
Console.error(f'Parsing {file}@{i}', f'{e} -> {traceback.format_exc()}') Console.error(f'Parsing {file}@{i}', f'{e} -> {traceback.format_exc()}')