Follow-up to #42 (grouped-star quick-win).
After the grouped-by-category dependencies graph lands, the next step is to populate true transitive edges between unit components so visualizers like https://cyclonedx.github.io/Sunshine/ can render a hierarchical graph.
Available infrastructure
The repo already ships a `TUsesClauseParser` that handles:
- interface + implementation `uses`
- program/library `uses`
- comment/string-literal stripping with a proper state machine
It's currently used as a fallback evidence source for LLVM targets without a MAP file. The same parser output can drive `dependencies[]` for all targets.
Proposed shape
For every `.pas` source we can locate (existing `UnitResolver` already does this), emit:
```json
{
"ref": "comp-System.SysUtils",
"dependsOn": ["comp-System", "comp-System.Types", "comp-Winapi.Windows"]
}
```
Units we only know as DCUs (closed-source third-party) stay leaves — no DCU header parsing in this issue.
Trade-offs to confirm in the design phase
- Cycle handling. Implementation-section uses can introduce cycles. CycloneDX allows cycles, but Sunshine may render them oddly — confirm in a small spike before committing to the shape.
- Auto-included compiler units. The Delphi linker pulls in many units the source never mentions (System, SysInit, …). Whether to also emit these as edges is a judgment call — proposal: emit them, but only as outgoing edges from the application/exe, not from every unit.
- Performance. A medium-sized Delphi project has 200–500 linked units. Parsing each .pas once is fine; doing it twice (once for evidence, once for deps) is not. The parser output should be cached by `UnitResolver` and reused.
- Missing source. When a unit's source is absent (Embarcadero RTL/VCL without source installed, third-party DCU-only libraries), the unit becomes a leaf. Document this in the SBOM via a `property` flag like `net.developer-experts.dx-comply:dependencies` = `unresolved-no-source`.
Acceptance criteria
- For a project with source available, `bom.json` carries a non-trivial transitive `dependencies[]` graph.
- Sunshine renders a multi-level chart, not a star.
- Existing CycloneDX 1.5 schema validation continues to pass.
- Performance budget: the additional graph build adds no more than ~10% to total SBOM generation time on the AlienInvasion fixture.
- Regression test: a fixture with three units (A uses B, B uses C) produces three edges (A→B, B→C, root→A or similar).
Related
Follow-up to #42 (grouped-star quick-win).
After the grouped-by-category dependencies graph lands, the next step is to populate true transitive edges between unit components so visualizers like https://cyclonedx.github.io/Sunshine/ can render a hierarchical graph.
Available infrastructure
The repo already ships a `TUsesClauseParser` that handles:
It's currently used as a fallback evidence source for LLVM targets without a MAP file. The same parser output can drive `dependencies[]` for all targets.
Proposed shape
For every `.pas` source we can locate (existing `UnitResolver` already does this), emit:
```json
{
"ref": "comp-System.SysUtils",
"dependsOn": ["comp-System", "comp-System.Types", "comp-Winapi.Windows"]
}
```
Units we only know as DCUs (closed-source third-party) stay leaves — no DCU header parsing in this issue.
Trade-offs to confirm in the design phase
Acceptance criteria
Related