diff --git a/src/codesnap/core/analyzer.py b/src/codesnap/core/analyzer.py new file mode 100644 index 0000000..1d9602b --- /dev/null +++ b/src/codesnap/core/analyzer.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +import ast +from pathlib import Path +from codesnap.core.complexity import ComplexityCalculator +from codesnap.core.dependency_graph import DependencyGraph +from codesnap.core.models import FileSummary, FunctionInfo + + +class CodeAnalyzer: + def __init__(self): + self.complexity_calc = ComplexityCalculator() + self.dep_graph = DependencyGraph() + + def analyze_file(self, file_path: Path) -> FileSummary: + with open(file_path, "r", encoding="utf-8") as f: + content = f.read() + + tree = ast.parse(content) + + functions = [] + for node in ast.walk(tree): + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): + func_info = self.complexity_calc.calculate_function_complexity(node, content) + functions.append(func_info) + + self.dep_graph.add_file(file_path, tree) + + imports = self._extract_imports(tree) + + return FileSummary( + file_path=str(file_path), + functions=functions, + total_complexity=sum(f.complexity for f in functions), + imports=imports, + ) + + def analyze_directory(self, dir_path: Path) -> list[FileSummary]: + results = [] + for py_file in dir_path.rglob("*.py"): + try: + summary = self.analyze_file(py_file) + results.append(summary) + except Exception as e: + print(f"Error analyzing {py_file}: {e}") + + return results + + def _extract_imports(self, tree: ast.AST) -> list[str]: + imports = [] + for node in ast.walk(tree): + if isinstance(node, ast.Import): + for alias in node.names: + imports.append(f"import {alias.name}") + elif isinstance(node, ast.ImportFrom): + module = node.module or "" + for alias in node.names: + imports.append(f"from {module} import {alias.name}") + return imports