from __future__ import annotations from dataclasses import dataclass, field from enum import Enum from typing import Any class NodeType(Enum): SOURCE = "SOURCE" SINK = "SINK" ENTRY_POINT = "ENTRY_POINT" FUNCTION = "FUNCTION" CLASS = "CLASS" CLUSTER = "CLUSTER" BOUNDARY = "BOUNDARY" MODULE = "MODULE" ENV_VAR = "ENV_VAR" PARAMETER = "PARAMETER" _CLUSTER_COUNTER: int = 0 def make_node_id(file_stem: str, identifier: str) -> str: return f"{file_stem}::{identifier}" def make_module_node_id(file_stem: str) -> str: return f"module::{file_stem}" def new_cluster_id() -> str: global _CLUSTER_COUNTER _CLUSTER_COUNTER += 1 return f"CLUSTER::{_CLUSTER_COUNTER:06d}" @dataclass class Node: id: str node_type: NodeType label: str file_path: str = "" line_start: int = 0 line_end: int = 0 is_entry_point: bool = False is_tainted: bool = False metadata: dict[str, Any] = field(default_factory=dict)