71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
|
|
class EntityType(Enum):
|
|
FILE = "file"
|
|
FUNCTION = "function"
|
|
CLASS = "class"
|
|
METHOD = "method"
|
|
IMPORT = "import"
|
|
VARIABLE = "variable"
|
|
CONSTANT = "constant"
|
|
|
|
|
|
@dataclass
|
|
class Entity:
|
|
name: str
|
|
entity_type: EntityType
|
|
file_path: Path
|
|
start_line: int
|
|
end_line: int
|
|
code: str = ""
|
|
attributes: dict = field(default_factory=dict)
|
|
parent: Optional["Entity"] = None
|
|
children: list["Entity"] = field(default_factory=list)
|
|
imports: list[str] = field(default_factory=list)
|
|
calls: list[str] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class ParserResult:
|
|
file_path: Path
|
|
entities: list[Entity] = field(default_factory=list)
|
|
imports: list[str] = field(default_factory=list)
|
|
errors: list[str] = field(default_factory=list)
|
|
language: str = ""
|
|
|
|
|
|
class BaseParser(ABC):
|
|
SUPPORTED_EXTENSIONS: list[str] = []
|
|
|
|
@abstractmethod
|
|
def parse(self, file_path: Path, content: str) -> ParserResult:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def extract_entities(self, tree, file_path: Path) -> list[Entity]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def extract_imports(self, content: str) -> list[str]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def extract_calls(self, content: str) -> list[str]:
|
|
pass
|
|
|
|
@classmethod
|
|
def can_parse(cls, file_path: Path) -> bool:
|
|
return file_path.suffix in cls.SUPPORTED_EXTENSIONS
|
|
|
|
@classmethod
|
|
def get_parser_for_file(cls, file_path: Path) -> Optional["BaseParser"]:
|
|
for parser_class in cls.__subclasses__():
|
|
if parser_class.can_parse(file_path):
|
|
return parser_class()
|
|
return None
|