Skip to content

Commit fbb716b

Browse files
committed
Update reactive pipeline documentation and diagrams
- Update ARCHITECTURE.md with current ReactiveSolver collections - Add table documenting all reactive collections in ReactiveSolver - Update pipeline stages to show full reactive flow - Regenerate reactive-pipeline.svg with detailed solver internals - Show timing breakdown (~0.7ms on cache hit for dead_code solving)
1 parent b98b29a commit fbb716b

File tree

3 files changed

+129
-73
lines changed

3 files changed

+129
-73
lines changed

analysis/reanalyze/ARCHITECTURE.md

Lines changed: 93 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ The reactive layer (`analysis/reactive/`) provides delta-based incremental updat
164164
The reactive pipeline computes issues directly from source files with **zero recomputation on cache hits**:
165165

166166
```
167-
Files → file_data → decls, annotations, refs → live (fixpoint) → dead_decls → issues → REPORT
168-
↓ ↓ ↓ ↓ ↓
169-
ReactiveFile ReactiveMerge ReactiveLiveness ReactiveSolver iter
170-
Collection (flatMap) (fixpoint) (join+join) (only)
167+
Files → file_data → decls, annotations, refs → live (fixpoint) → dead/live_decls → issues → REPORT
168+
↓ ↓ ↓ ↓ ↓
169+
ReactiveFile ReactiveMerge ReactiveLiveness ReactiveSolver iter
170+
Collection (flatMap) (fixpoint) (multiple joins) (only)
171171
```
172172

173-
**Key property**: When no files change, no computation happens. All reactive collections are stable. Only the final `collect_issues` call iterates (O(issues)).
173+
**Key property**: When no files change, no computation happens. All reactive collections are stable. Only the final `collect_issues` call iterates pre-computed collections (O(issues)).
174174

175175
### Pipeline Stages
176176

@@ -179,11 +179,28 @@ Files → file_data → decls, annotations, refs → live (fixpoint) → dead_de
179179
| **File Processing** | `.cmt` files | `file_data` | `ReactiveFileCollection` |
180180
| **Merge** | `file_data` | `decls`, `annotations`, `refs` | `flatMap` |
181181
| **Liveness** | `refs`, `annotations` | `live` (positions) | `fixpoint` |
182-
| **Dead Decls** | `decls`, `live` | `dead_decls` | `join` (left-join, filter `None`: decls where NOT in live) |
183-
| **Issues** | `dead_decls`, `annotations` | `issues` | `join` (filter by annotation, generate Issue.t) |
184-
| **Report** | `issues` | stdout | `iter` (ONLY iteration in entire pipeline) |
185-
186-
**Note**: Optional args analysis (unused/redundant arguments) is not yet in the reactive pipeline - it still uses the non-reactive path. TODO: Add `live_decls + cross_file_items → optional_args_issues` to the reactive pipeline.
182+
| **Dead/Live Partition** | `decls`, `live` | `dead_decls`, `live_decls` | `join` (partition by liveness) |
183+
| **Dead Modules** | `dead_decls`, `live_decls` | `dead_modules` | `flatMap` + `join` (anti-join) |
184+
| **Per-File Grouping** | `dead_decls`, `refs` | `dead_decls_by_file`, `refs_by_file` | `flatMap` with merge |
185+
| **Per-File Issues** | `dead_decls_by_file`, `annotations` | `issues_by_file` | `flatMap` (sort + filter + generate) |
186+
| **Incorrect @dead** | `live_decls`, `annotations` | `incorrect_dead_decls` | `join` (live with Dead annotation) |
187+
| **Module Issues** | `dead_modules`, `issues_by_file` | `dead_module_issues` | `flatMap` + `join` |
188+
| **Report** | all issue collections | stdout | `iter` (ONLY iteration) |
189+
190+
### ReactiveSolver Collections
191+
192+
| Collection | Type | Description |
193+
|------------|------|-------------|
194+
| `dead_decls` | `(pos, Decl.t)` | Declarations NOT in live set |
195+
| `live_decls` | `(pos, Decl.t)` | Declarations IN live set |
196+
| `dead_modules` | `(Name.t, Location.t)` | Modules with only dead declarations (anti-join) |
197+
| `dead_decls_by_file` | `(file, Decl.t list)` | Dead decls grouped by file |
198+
| `value_refs_from_by_file` | `(file, (pos, PosSet.t) list)` | Refs grouped by source file (for hasRefBelow) |
199+
| `issues_by_file` | `(file, Issue.t list * Name.t list)` | Per-file issues + reported modules |
200+
| `incorrect_dead_decls` | `(pos, Decl.t)` | Live decls with @dead annotation |
201+
| `dead_module_issues` | `(Name.t, Issue.t)` | Module issues (join of dead_modules + modules_with_reported) |
202+
203+
**Note**: Optional args analysis (unused/redundant arguments) is not yet in the reactive pipeline - it still uses the non-reactive path (~8-14ms). TODO: Add `live_decls + cross_file_items → optional_args_issues` to the reactive pipeline.
187204

188205
### Reactive Pipeline Diagram
189206

@@ -192,59 +209,72 @@ Files → file_data → decls, annotations, refs → live (fixpoint) → dead_de
192209
![Reactive Pipeline](diagrams/reactive-pipeline.svg)
193210

194211
```
195-
┌─────────────────────────────────────────────────────────────────────────────┐
196-
│ REACTIVE ANALYSIS PIPELINE │
197-
│ │
198-
│ ┌──────────┐ │
199-
│ │ .cmt │ │
200-
│ │ files │ │
201-
│ └────┬─────┘ │
202-
│ │ │
203-
│ ▼ │
204-
│ ┌──────────────────────┐ │
205-
│ │ ReactiveFileCollection│ File change detection + caching │
206-
│ │ file_data │ │
207-
│ └────┬─────────────────┘ │
208-
│ │ flatMap │
209-
│ ▼ │
210-
│ ┌──────────────────────┐ │
211-
│ │ ReactiveMerge │ Derives collections from file_data │
212-
│ │ ┌──────┐ ┌────────┐ │ │
213-
│ │ │decls │ │ refs │ │ │
214-
│ │ └──┬───┘ └───┬────┘ │ │
215-
│ │ │ ┌──────┴─────┐ │ │
216-
│ │ │ │annotations │ │ │
217-
│ │ │ └──────┬─────┘ │ │
218-
│ └────┼─────────┼───────┘ │
219-
│ │ │ │
220-
│ │ ▼ │
221-
│ │ ┌─────────────────────┐ │
222-
│ │ │ ReactiveLiveness │ roots + edges → live (fixpoint) │
223-
│ │ │ ┌──────┐ ┌──────┐ │ │
224-
│ │ │ │roots │→│ live │ │ │
225-
│ │ │ └──────┘ └──┬───┘ │ │
226-
│ │ └──────────────┼──────┘ │
227-
│ │ │ │
228-
│ ▼ ▼ │
229-
│ ┌─────────────────────────────────┐ │
230-
│ │ ReactiveSolver │ Pure reactive joins (NO iteration) │
231-
│ │ │ │
232-
│ │ decls ──┬──► dead_decls ──┬──► issues │
233-
│ │ │ ↑ │ ↑ │
234-
│ │ live ───┘ (join, keep │ (join with annotations) │
235-
│ │ if NOT in live)│ │
236-
│ │ annotations ──────────────┘ │
237-
│ │ │ │
238-
│ │ (Optional args: TODO - not yet reactive) │
239-
│ └─────────────────────────────────┘ │
240-
│ │ │
241-
│ ▼ │
242-
│ ┌─────────────────────────────────┐ │
243-
│ │ REPORT │ ONLY iteration: O(issues) │
244-
│ │ collect_issues → Log_.warning │ (linear in number of issues) │
245-
│ └─────────────────────────────────┘ │
246-
│ │
247-
└─────────────────────────────────────────────────────────────────────────────┘
212+
┌───────────────────────────────────────────────────────────────────────────────────┐
213+
│ REACTIVE ANALYSIS PIPELINE │
214+
│ │
215+
│ ┌──────────┐ │
216+
│ │ .cmt │ │
217+
│ │ files │ │
218+
│ └────┬─────┘ │
219+
│ │ │
220+
│ ▼ │
221+
│ ┌──────────────────────┐ │
222+
│ │ ReactiveFileCollection│ File change detection + caching │
223+
│ │ file_data │ │
224+
│ └────┬─────────────────┘ │
225+
│ │ flatMap │
226+
│ ▼ │
227+
│ ┌──────────────────────┐ │
228+
│ │ ReactiveMerge │ Derives collections from file_data │
229+
│ │ ┌──────┐ ┌────────┐ │ │
230+
│ │ │decls │ │ refs │ │ │
231+
│ │ └──┬───┘ └───┬────┘ │ │
232+
│ │ │ ┌──────┴─────┐ │ │
233+
│ │ │ │annotations │ │ │
234+
│ │ │ └──────┬─────┘ │ │
235+
│ └────┼─────────┼───────┘ │
236+
│ │ │ │
237+
│ │ ▼ │
238+
│ │ ┌─────────────────────┐ │
239+
│ │ │ ReactiveLiveness │ roots + edges → live (fixpoint) │
240+
│ │ │ ┌──────┐ ┌──────┐ │ │
241+
│ │ │ │roots │→│ live │ │ │
242+
│ │ │ └──────┘ └──┬───┘ │ │
243+
│ │ └──────────────┼──────┘ │
244+
│ │ │ │
245+
│ ▼ ▼ │
246+
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
247+
│ │ ReactiveSolver │ │
248+
│ │ │ │
249+
│ │ decls ──┬──► dead_decls ──┬──► dead_decls_by_file ──► issues_by_file │ │
250+
│ │ │ │ │ │ │ │ │
251+
│ │ live ───┤ │ │ │ ▼ │ │
252+
│ │ │ ▼ │ │ modules_with_reported │ │
253+
│ │ │ dead_modules ─┼────────────┼──────────────┬─────────┘ │ │
254+
│ │ │ ↑ │ │ │ │ │
255+
│ │ └──► live_decls ──┼────────────┘ ▼ │ │
256+
│ │ │ │ dead_module_issues │ │
257+
│ │ │ │ │ │
258+
│ │ annotations ─────┼────────┴──► incorrect_dead_decls │ │
259+
│ │ │ │ │
260+
│ │ value_refs_from ─┴──► refs_by_file (used by issues_by_file for hasRefBelow)│ │
261+
│ │ │ │
262+
│ │ (Optional args: TODO - not yet reactive, ~8-14ms) │ │
263+
│ └─────────────────────────────────────────────────────────────────────────────┘ │
264+
│ │ │
265+
│ ▼ │
266+
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
267+
│ │ REPORT │ │
268+
│ │ │ │
269+
│ │ collect_issues iterates pre-computed reactive collections: │ │
270+
│ │ - incorrect_dead_decls (~0.04ms) │ │
271+
│ │ - issues_by_file (~0.6ms) │ │
272+
│ │ - dead_module_issues (~0.06ms) │ │
273+
│ │ │ │
274+
│ │ Total dead_code solving: ~0.7ms on cache hit │ │
275+
│ └─────────────────────────────────────────────────────────────────────────────┘ │
276+
│ │
277+
└───────────────────────────────────────────────────────────────────────────────────┘
248278
```
249279

250280
### Delta Propagation

analysis/reanalyze/diagrams/reactive-pipeline.mmd

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,18 @@ flowchart TB
3939
end
4040

4141
subgraph Solver["ReactiveSolver"]
42-
DEAD["dead"]
43-
ISSUES["issues"]
42+
DEAD_DECLS["dead_decls"]
43+
LIVE_DECLS["live_decls"]
44+
DEAD_MODULES["dead_modules"]
45+
DEAD_BY_FILE["dead_by_file"]
46+
REFS_BY_FILE["refs_by_file"]
47+
ISSUES_BY_FILE["issues_by_file"]
48+
INCORRECT["incorrect_dead"]
49+
MOD_REPORTED["mod_reported"]
50+
MOD_ISSUES["mod_issues"]
4451
end
4552

46-
subgraph Report["Report"]
53+
subgraph Report["Report (iter only)"]
4754
OUTPUT[("REPORT")]
4855
end
4956

@@ -76,12 +83,31 @@ flowchart TB
7683
EDGES --> FP
7784
FP -->|"fixpoint"| LIVE
7885

79-
DECLS -->|"join"| DEAD
80-
LIVE -->|"left-join, filter None"| DEAD
81-
DEAD -->|"join"| ISSUES
82-
ANNOT -->|"join"| ISSUES
86+
DECLS -->|"join (NOT in live)"| DEAD_DECLS
87+
LIVE -->|"join"| DEAD_DECLS
88+
DECLS -->|"join (IN live)"| LIVE_DECLS
89+
LIVE -->|"join"| LIVE_DECLS
8390

84-
ISSUES -->|"iter"| OUTPUT
91+
DEAD_DECLS -->|"flatMap (anti-join)"| DEAD_MODULES
92+
LIVE_DECLS -->|"flatMap (anti-join)"| DEAD_MODULES
93+
94+
DEAD_DECLS -->|"flatMap by file"| DEAD_BY_FILE
95+
VREFS -->|"flatMap by file"| REFS_BY_FILE
96+
97+
DEAD_BY_FILE -->|"flatMap"| ISSUES_BY_FILE
98+
ANNOT -->|"filter"| ISSUES_BY_FILE
99+
REFS_BY_FILE -->|"hasRefBelow"| ISSUES_BY_FILE
100+
101+
LIVE_DECLS -->|"join (@dead)"| INCORRECT
102+
ANNOT -->|"join (@dead)"| INCORRECT
103+
104+
ISSUES_BY_FILE -->|"flatMap"| MOD_REPORTED
105+
DEAD_MODULES -->|"join"| MOD_ISSUES
106+
MOD_REPORTED -->|"join"| MOD_ISSUES
107+
108+
ISSUES_BY_FILE -->|"iter"| OUTPUT
109+
INCORRECT -->|"iter"| OUTPUT
110+
MOD_ISSUES -->|"iter"| OUTPUT
85111

86112
classDef fileLayer fill:#e8f4fd,stroke:#4a90d9,stroke-width:2px
87113
classDef extracted fill:#f0f7e6,stroke:#6b8e23,stroke-width:2px
@@ -98,5 +124,5 @@ flowchart TB
98124
class EXCREF,EXCDECL,RESOLVED excDeps
99125
class DR declRefs
100126
class ROOTS,EDGES,FP,LIVE liveness
101-
class DEAD,ISSUES solver
127+
class DEAD_DECLS,LIVE_DECLS,DEAD_MODULES,DEAD_BY_FILE,REFS_BY_FILE,ISSUES_BY_FILE,INCORRECT,MOD_REPORTED,MOD_ISSUES solver
102128
class OUTPUT output

analysis/reanalyze/diagrams/reactive-pipeline.svg

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)