MCPcopy Create free account
hub / github.com/FonaTech/Clouds-Coder / DependencyAnalyzer

Class DependencyAnalyzer

split_coder.py:824–936  ·  view source on GitHub ↗

Analyzes cross-module name dependencies with scope awareness.

Source from the content-addressed store, hash-verified

822# ─── Dependency Analyzer ──────────────────────────────────────────────────────
823
824class DependencyAnalyzer:
825 """Analyzes cross-module name dependencies with scope awareness."""
826
827 def __init__(self, analyzer: ArchitectureAnalyzer, nodes: List[NodeInfo]) -> None:
828 self.analyzer = analyzer
829 self.nodes = nodes
830 # Build symbol → module map (only non-import nodes)
831 self.symbol_to_module: Dict[str, str] = {}
832 for n in nodes:
833 if n.kind not in ("import",) and not n.name.startswith("_import_") and not n.name.startswith("_try_"):
834 self.symbol_to_module[n.name] = n.target_module
835
836 def compute_dependency_map(self, module_path: str, module_nodes: List[NodeInfo]) -> Dict[str, Set[str]]:
837 """Return dependency module -> symbols for one generated module."""
838 deps: Dict[str, Set[str]] = defaultdict(set)
839 for node in module_nodes:
840 if node.kind == "import":
841 continue
842 for name in self._node_referenced_symbols(node):
843 source_mod = self.symbol_to_module.get(name)
844 if source_mod and source_mod != module_path and source_mod != "_imports":
845 deps[source_mod].add(name)
846 return deps
847
848 def compute_imports(self, module_path: str, module_nodes: List[NodeInfo]) -> List[str]:
849 """
850 For a given output module, compute the correct relative `from .X import Y`
851 statements needed to satisfy cross-module references.
852 Returns sorted list of import lines.
853 """
854 deps = self.compute_dependency_map(module_path, module_nodes)
855
856 import_lines = []
857 for dep_mod, names in sorted(deps.items()):
858 if not names:
859 continue
860 rel = self._relative_import(module_path, dep_mod)
861 names_str = ", ".join(sorted(names))
862 import_lines.append(f"from {rel} import {names_str}")
863
864 return import_lines
865
866 def compute_referenced_names(self, module_nodes: List[NodeInfo]) -> Set[str]:
867 """Return all referenced names across nodes in one generated module."""
868 referenced: Set[str] = set()
869 for node in module_nodes:
870 if node.kind == "import":
871 continue
872 referenced.update(self._node_referenced_symbols(node))
873 return referenced
874
875 def _node_referenced_symbols(self, node: NodeInfo) -> Set[str]:
876 source = self.analyzer.get_source_lines(node.lineno, node.end_lineno)
877 if not source.strip():
878 return set()
879 try:
880 table = symtable.symtable(source, str(self.analyzer.source_path), "exec")
881 except SyntaxError:

Callers 1

runMethod · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected