Handle a Nix ``binding`` node (``attrpath = expr;``). - Flattens dotted attrpaths into a single dotted node name (``packages.default``). - In ``flake.nix``, ``inputs. .url = "..."`` bindings emit an ``IMPORTS_FROM`` edge with target = the URL string, and no
(
self,
node,
source: bytes,
language: str,
file_path: str,
nodes: list[NodeInfo],
edges: list[EdgeInfo],
enclosing_class: Optional[str],
enclosing_func: Optional[str],
import_map: Optional[dict[str, str]],
defined_names: Optional[set[str]],
_depth: int,
)
| 2787 | return results |
| 2788 | |
| 2789 | def _extract_nix_constructs( |
| 2790 | self, |
| 2791 | node, |
| 2792 | source: bytes, |
| 2793 | language: str, |
| 2794 | file_path: str, |
| 2795 | nodes: list[NodeInfo], |
| 2796 | edges: list[EdgeInfo], |
| 2797 | enclosing_class: Optional[str], |
| 2798 | enclosing_func: Optional[str], |
| 2799 | import_map: Optional[dict[str, str]], |
| 2800 | defined_names: Optional[set[str]], |
| 2801 | _depth: int, |
| 2802 | ) -> bool: |
| 2803 | """Handle a Nix ``binding`` node (``attrpath = expr;``). |
| 2804 | |
| 2805 | - Flattens dotted attrpaths into a single dotted node name |
| 2806 | (``packages.default``). |
| 2807 | - In ``flake.nix``, ``inputs.<name>.url = "..."`` bindings emit an |
| 2808 | ``IMPORTS_FROM`` edge with target = the URL string, and no node. |
| 2809 | - All other bindings become ``Function`` nodes (matching the |
| 2810 | Bash/Elixir convention for "the graph's addressable things") with a |
| 2811 | CONTAINS edge from the File. |
| 2812 | - The RHS is scanned for ``import <path>`` / ``callPackage <path> ...`` |
| 2813 | applications; each emits an ``IMPORTS_FROM`` edge (relative paths |
| 2814 | are resolved against the caller's directory when possible). |
| 2815 | - Recurses into the RHS so nested bindings (e.g. inside |
| 2816 | ``let ... in { ... }`` or ``outputs = { ... }: { ... }``) are |
| 2817 | discovered and flattened as their own top-level nodes. |
| 2818 | |
| 2819 | Returns True (Nix has no other node-type dispatches in the walker). |
| 2820 | """ |
| 2821 | attrpath_node = None |
| 2822 | rhs_node = None |
| 2823 | for sub in node.children: |
| 2824 | if sub.type == "attrpath": |
| 2825 | attrpath_node = sub |
| 2826 | elif sub.type not in ("=", ";") and attrpath_node is not None: |
| 2827 | # First non-attrpath, non-punctuation child is the RHS. |
| 2828 | if rhs_node is None: |
| 2829 | rhs_node = sub |
| 2830 | if attrpath_node is None or rhs_node is None: |
| 2831 | return False |
| 2832 | |
| 2833 | parts = self._nix_attrpath_parts(attrpath_node) |
| 2834 | if not parts: |
| 2835 | return False |
| 2836 | name = ".".join(parts) |
| 2837 | line = node.start_point[0] + 1 |
| 2838 | |
| 2839 | # --- Flake input URL: inputs.<name>.url = "..." ------------------ |
| 2840 | # Flat form: ``inputs.nixpkgs.url = "github:...";`` — emit one edge, |
| 2841 | # skip node creation (this is metadata, not a graph "thing"). |
| 2842 | if ( |
| 2843 | self._is_nix_flake_file(file_path) |
| 2844 | and len(parts) >= 2 |
| 2845 | and parts[0] == "inputs" |
| 2846 | and parts[-1] == "url" |
no test coverage detected