Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
4442d8c
Experiment: Reactive analysis with skip-lite CMT cache
cristianoc Dec 15, 2025
7f482bf
Enable create-sourcedirs by default in rewatch
cristianoc Dec 15, 2025
9265b64
Refine reactive_file_collection representation
cristianoc Dec 15, 2025
210862e
Replace C++ marshal_cache with pure OCaml implementation
cristianoc Dec 15, 2025
dfdf010
Move reactive combinators to dedicated library with composition support
cristianoc Dec 16, 2025
b2ff1c1
Integrate ReactiveMerge into runAnalysis
cristianoc Dec 16, 2025
f7066d2
Add reactive combinators (lookup, join) and reactive type/exception deps
cristianoc Dec 16, 2025
d686fd6
Fix reactive mode @genType handling and update architecture docs
cristianoc Dec 16, 2025
038d0a0
Add store abstractions to eliminate merge overhead in reactive mode
cristianoc Dec 16, 2025
7eb1fba
Remove backward solver, use forward fixpoint for liveness
cristianoc Dec 16, 2025
30d3310
Remove refs_to storage, compute lazily only when needed
cristianoc Dec 16, 2025
020712e
Implement incremental reactive fixpoint combinator
cristianoc Dec 16, 2025
211422c
Fix external refs tracking with explicit join dependency
cristianoc Dec 16, 2025
2517c32
Fix reactive fixpoint re-derivation on removals
cristianoc Dec 16, 2025
9defed6
DCE: forward-model debug output (no refs_to)
cristianoc Dec 16, 2025
5f3c964
Refactor hasRefBelow to use on-demand per-decl search
cristianoc Dec 16, 2025
49bcf5c
Update ReactiveSolver TODO with accurate status and missing issues
cristianoc Dec 16, 2025
595e8ef
Add optional args to reactive pipeline
cristianoc Dec 16, 2025
3b6f878
Format ReactiveSolver and Reanalyze
cristianoc Dec 16, 2025
96a122d
Make dead_modules reactive in ReactiveSolver
cristianoc Dec 16, 2025
97cf8ae
Remove resolvedDead mutation - use reactive liveness check
cristianoc Dec 16, 2025
05c83f9
Use per-file issue generation for isInsideReportedValue
cristianoc Dec 16, 2025
5ef231e
Make dead_decls_by_file reactive and remove report mutation
cristianoc Dec 16, 2025
c25272c
Make issues_by_file reactive
cristianoc Dec 16, 2025
46012ef
Optimize hasRefBelow to use per-file refs
cristianoc Dec 16, 2025
fbc5bbc
Make incorrect @dead detection reactive
cristianoc Dec 16, 2025
b98b29a
Make dead module issues reactive
cristianoc Dec 16, 2025
fbb716b
Update reactive pipeline documentation and diagrams
cristianoc Dec 16, 2025
6db81bc
Add update counters to reactive collections
cristianoc Dec 16, 2025
0f96d10
Add stats printing for ReactiveLiveness collections
cristianoc Dec 16, 2025
2f6ef60
Add Batch delta type for efficient bulk updates
cristianoc Dec 17, 2025
ed29f4d
Use batch processing for ReactiveFileCollection
cristianoc Dec 17, 2025
42d0efe
Optimize fixpoint batch handling with single BFS expansion
cristianoc Dec 17, 2025
aa1941e
Revert "Optimize fixpoint batch handling with single BFS expansion"
cristianoc Dec 17, 2025
d4092ed
Reactive: add refined stats tracking, remove V1, rename ReactiveV2 to…
cristianoc Dec 17, 2025
87c6dff
Add -mermaid flag and update reactive pipeline diagram
cristianoc Dec 17, 2025
a438152
Update ARCHITECTURE.md to reflect current reactive system
cristianoc Dec 17, 2025
fcb834e
Simplify reactive pipeline diagram with clearer names
cristianoc Dec 17, 2025
b895d98
Add full auto-generated reactive pipeline diagram
cristianoc Dec 17, 2025
8635190
Keep only .mmd source for full diagram (no SVG)
cristianoc Dec 17, 2025
393c4c2
Add edge labels to auto-generated Mermaid diagram
cristianoc Dec 17, 2025
cb79a21
Represent combinators as diamond nodes in Mermaid diagram
cristianoc Dec 17, 2025
8a1b2f3
Add colored combinator nodes to Mermaid diagram
cristianoc Dec 17, 2025
dfcb63e
Fix dead module location and hasRefBelow in reactive mode
cristianoc Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion analysis/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(dirs bin src reanalyze vendor)
(dirs bin src reactive reanalyze vendor)

(env
(dev
Expand Down
15 changes: 15 additions & 0 deletions analysis/reactive/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: build test clean

# Build the reactive library
build:
dune build src/

# Run all tests
test:
dune build test/ReactiveTest.exe
dune exec test/ReactiveTest.exe

# Clean build artifacts
clean:
dune clean

109 changes: 109 additions & 0 deletions analysis/reactive/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Reactive Collections Library

A library for incremental computation using reactive collections with delta-based updates.

## Overview

This library provides composable reactive collections that automatically propagate changes through a computation graph. When source data changes, only the affected parts of derived collections are recomputed.

### Key Features

- **Delta-based updates**: Changes propagate as `Set`, `Remove`, or `Batch` deltas
- **Glitch-free semantics**: Topological scheduling ensures consistent updates
- **Composable combinators**: `flatMap`, `join`, `union`, `fixpoint`
- **Incremental fixpoint**: Efficient transitive closure with support for additions and removals

## Usage

```ocaml
open Reactive

(* Create a source collection *)
let (files, emit) = source ~name:"files" ()

(* Derive collections with combinators *)
let decls = flatMap ~name:"decls" files
~f:(fun _path data -> data.declarations)
()

let refs = flatMap ~name:"refs" files
~f:(fun _path data -> data.references)
~merge:PosSet.union
()

(* Join collections *)
let resolved = join ~name:"resolved" refs decls
~key_of:(fun pos _ref -> pos)
~f:(fun pos ref decl_opt -> ...)
()

(* Compute transitive closure *)
let reachable = fixpoint ~name:"reachable"
~init:roots
~edges:graph
()

(* Emit changes *)
emit (Set ("file.res", file_data))
emit (Batch [set "a.res" data_a; set "b.res" data_b])
```

## Combinators

| Combinator | Description |
|------------|-------------|
| `source` | Create a mutable source collection |
| `flatMap` | Transform and flatten entries, with optional merge |
| `join` | Look up keys from left collection in right collection |
| `union` | Combine two collections, with optional merge for conflicts |
| `fixpoint` | Compute transitive closure incrementally |

## Building & Testing

```bash
# Build the library
make build

# Run all tests
make test

# Clean build artifacts
make clean
```

## Test Structure

Tests are organized by theme:

| File | Description |
|------|-------------|
| `FlatMapTest.ml` | FlatMap combinator tests |
| `JoinTest.ml` | Join combinator tests |
| `UnionTest.ml` | Union combinator tests |
| `FixpointBasicTest.ml` | Basic fixpoint graph traversal |
| `FixpointIncrementalTest.ml` | Incremental fixpoint updates |
| `BatchTest.ml` | Batch processing tests |
| `IntegrationTest.ml` | End-to-end file processing |
| `GlitchFreeTest.ml` | Glitch-free scheduler tests |

## Glitch-Free Semantics

The scheduler ensures that derived collections never see inconsistent intermediate states:

1. **Topological levels**: Each node has a level based on its dependencies
2. **Accumulate phase**: All deltas at a level are collected before processing
3. **Propagate phase**: Nodes process accumulated deltas in level order

This prevents issues like:
- Anti-joins seeing partial data (e.g., refs without matching decls)
- Multi-level unions causing spurious additions/removals

## Usage in Reanalyze

This library powers the reactive dead code analysis in reanalyze:

- `ReactiveFileCollection`: Manages CMT file processing
- `ReactiveMerge`: Merges per-file data into global collections
- `ReactiveLiveness`: Computes live declarations via fixpoint
- `ReactiveSolver`: Generates dead code issues reactively

1 change: 1 addition & 0 deletions analysis/reactive/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(dirs src test)
Loading
Loading