(n)
| 2674 | results: list[tuple[str, int]] = [] |
| 2675 | |
| 2676 | def visit(n) -> None: |
| 2677 | if n is None: |
| 2678 | return |
| 2679 | if n.type == "binding": |
| 2680 | inner_path = None |
| 2681 | inner_rhs = None |
| 2682 | for sub in n.children: |
| 2683 | if sub.type == "attrpath": |
| 2684 | inner_path = sub |
| 2685 | elif sub.type not in ("=", ";") and inner_path is not None: |
| 2686 | if inner_rhs is None: |
| 2687 | inner_rhs = sub |
| 2688 | if inner_path is not None and inner_rhs is not None: |
| 2689 | parts = self._nix_attrpath_parts(inner_path) |
| 2690 | if ( |
| 2691 | parts |
| 2692 | and parts[-1] == "url" |
| 2693 | and inner_rhs.type == "string_expression" |
| 2694 | ): |
| 2695 | for c in inner_rhs.children: |
| 2696 | if c.type == "string_fragment": |
| 2697 | url = c.text.decode("utf-8", errors="replace") |
| 2698 | results.append((url, n.start_point[0] + 1)) |
| 2699 | break |
| 2700 | return # leaf binding — no children to recurse into |
| 2701 | # Non-url binding: still recurse so a deeper url survives |
| 2702 | if inner_rhs.type == "attrset_expression": |
| 2703 | visit(inner_rhs) |
| 2704 | return |
| 2705 | for c in n.children: |
| 2706 | visit(c) |
| 2707 | |
| 2708 | visit(attrset_node) |
| 2709 | return results |
nothing calls this directly
no test coverage detected