Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 13 additions & 22 deletions analysis/reanalyze/DEADCODE_REFACTOR_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -613,32 +613,23 @@ add `@dead` annotations.

## Optional Future Tasks

### Optional Task: Make OptionalArgs tracking immutable
### Optional Task: Make OptionalArgs tracking immutable

**Value**: Currently `CrossFileItems.process_optional_args` mutates `optionalArgs` inside declarations.
Making this immutable would complete the pure pipeline.
**Value**: `OptionalArgs.t` is now fully immutable. No mutation of declarations.

**Current state**:
- `OptionalArgs.t` inside `decl.declKind = Value {optionalArgs}` is mutable
- `OptionalArgs.call` and `OptionalArgs.combine` mutate the record
- This happens after merge but before solver
**Changes made**:
- [x] Made `OptionalArgs.t` immutable (no mutable fields)
- [x] Added pure functions: `apply_call`, `combine_pair`
- [x] Created `OptionalArgsState` module in `Common.ml` for state map
- [x] `compute_optional_args_state` returns immutable state map
- [x] `DeadOptionalArgs.check` looks up state from map

**Why it's acceptable now**:
- Mutation happens in a well-defined phase (after merge, before solver)
- Solver sees effectively immutable data
- Order independence is maintained (calls accumulate, order doesn't matter)
**Architecture**:
- Declaration's `optionalArgs` = initial state (what args exist)
- `OptionalArgsState.t` = computed state (after all calls/combines)
- Solver uses `OptionalArgsState.find_opt` to get final state

**Changes needed**:
- [ ] Make `OptionalArgs.t` an immutable data structure
- [ ] Collect call info during AST processing as `OptionalArgCalls.builder`
- [ ] Return calls from `process_cmt_file` in `file_data`
- [ ] Merge all calls after file processing
- [ ] Build final `OptionalArgs` state from merged calls (pure)
- [ ] Store immutable `OptionalArgs` in declarations

**Estimated effort**: Medium-High (touches core data structures)

**Priority**: Low (current design works, just not fully pure)
**Status**: Complete ✅

---

Expand Down
14 changes: 6 additions & 8 deletions analysis/reanalyze/src/AnalysisResult.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
The solver returns this instead of logging directly.
All side effects (logging, JSON output) happen in the reporting phase. *)

open Common

type t = {issues: issue list}
type t = {issues: Issue.t list}
(** Immutable analysis result *)

let empty = {issues = []}
Expand All @@ -20,11 +18,11 @@ let get_issues result = result.issues |> List.rev
let issue_count result = List.length result.issues

(** Create a dead code issue *)
let make_dead_issue ~loc ~deadWarning ~path ~message =
let make_dead_issue ~loc ~deadWarning ~path ~message : Issue.t =
{
name =
Issue.name =
(match deadWarning with
| WarningDeadException -> "Warning Dead Exception"
| Issue.WarningDeadException -> "Warning Dead Exception"
| WarningDeadType -> "Warning Dead Type"
| WarningDeadValue -> "Warning Dead Value"
| WarningDeadValueWithSideEffects ->
Expand All @@ -36,9 +34,9 @@ let make_dead_issue ~loc ~deadWarning ~path ~message =
}

(** Create a dead module issue *)
let make_dead_module_issue ~loc ~moduleName =
let make_dead_module_issue ~loc ~moduleName : Issue.t =
{
name = "Warning Dead Module";
Issue.name = "Warning Dead Module";
severity = Warning;
loc;
description =
Expand Down
14 changes: 6 additions & 8 deletions analysis/reanalyze/src/AnalysisResult.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@
The solver returns this instead of logging directly.
All side effects (logging, JSON output) happen in the reporting phase. *)

open Common

type t
(** Immutable analysis result *)

val empty : t
(** Empty result with no issues *)

val add_issue : t -> issue -> t
val add_issue : t -> Issue.t -> t
(** Add a single issue to the result *)

val add_issues : t -> issue list -> t
val add_issues : t -> Issue.t list -> t
(** Add multiple issues to the result *)

val get_issues : t -> issue list
val get_issues : t -> Issue.t list
(** Get all issues in order they were added *)

val issue_count : t -> int
Expand All @@ -27,11 +25,11 @@ val issue_count : t -> int

val make_dead_issue :
loc:Location.t ->
deadWarning:deadWarning ->
deadWarning:Issue.deadWarning ->
path:string ->
message:string ->
issue
Issue.t
(** Create a dead code warning issue *)

val make_dead_module_issue : loc:Location.t -> moduleName:Name.t -> issue
val make_dead_module_issue : loc:Location.t -> moduleName:Name.t -> Issue.t
(** Create a dead module warning issue *)
20 changes: 20 additions & 0 deletions analysis/reanalyze/src/Cli.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(** Command-line interface options for reanalyze.
These refs are set by argument parsing in Reanalyze.ml *)

let debug = ref false
let ci = ref false

(** The command was a -cmt variant (e.g. -exception-cmt) *)
let cmtCommand = ref false

let experimental = ref false
let json = ref false

(* names to be considered live values *)
let liveNames = ref ([] : string list)

(* paths of files where all values are considered live *)
let livePaths = ref ([] : string list)

(* paths of files to exclude from analysis *)
let excludePaths = ref ([] : string list)
221 changes: 0 additions & 221 deletions analysis/reanalyze/src/Common.ml

This file was deleted.

Loading
Loading