Find and remove dead code and unused APIs in OCaml projects
1(** Warning parsing and handling for prune
2
3 This module parses compiler warnings and errors from dune build output.
4
5 {2 Location precision in compiler warnings}
6
7 The OCaml compiler provides different levels of location precision for
8 different warnings. Understanding what the location points to is crucial for
9 determining whether we need additional tools (merlin) to find the complete
10 construct to remove.
11
12 {3 Warnings that point to the COMPLETE construct (can be removed directly)}
13
14 {ul
15 {- **Warning 33 (unused open)**: Points to the entire open statement
16 Example: "File \"lib/foo.ml\", line 3, characters 0-15:"
17 {[
18 open Module (* characters 0-15 cover the whole statement *)
19 ^^^^^^^^^^^^
20 ]}
21 }
22 }
23
24 {ul
25 {- **Warning 34 (unused type)**: Points to the entire type definition
26 Example: "File \"lib/foo.mli\", line 5, characters 0-24:"
27 {[
28 type t = int (* characters 0-24 cover the whole definition *)
29 ^^^^^^^^^^^^
30 ]}
31 }
32 }
33
34 {ul
35 {- **Warning 69 (unused field)**: Points to the complete field definition
36 within a record type Example: "File \"lib/foo.ml\", line 8, characters
37 2-20:"
38 {[
39 type t = {
40 field : string; (* characters 2-20 cover the entire "field : string;" *)
41 ^^^^^^^^^^^^^^^^^^
42 other : int;
43 }
44 ]}
45 Note: Character-level removal is used (replacing with spaces) to
46 preserve the record structure and avoid syntax errors
47 }
48 }
49
50 {3 Warnings that point to JUST THE IDENTIFIER (need merlin to find full
51 construct)}
52
53 {ul
54 {- **Warning 32 (unused value)**: Points only to the value name Example:
55 "File \"lib/foo.ml\", line 15, characters 4-17:"
56 {[
57 let unused_value = complex_expression (* characters 4-17 cover only "unused_value" *)
58 ^^^^^^^^^^^^
59 ]}
60 Action needed: Use merlin enclosing to find the complete let binding
61 }
62 }
63
64 {3 Errors requiring special handling}
65
66 - **Signature mismatch errors**: Points to declaration in .mli file Example:
67 "File \"lib/foo.mli\", line 2, characters 0-35:" Action: For .mli files,
68 use merlin outline (already have full bounds)
69
70 {ul
71 {- **Unbound record field errors**: Points to just the field name in record
72 construction Example: "File \"lib/foo.ml\", line 10, characters 35-42:"
73 {[
74 let r = { x = 1; y = 2; unbound = 3 } (* characters 35-42 point to "unbound" only *)
75 ^^^^^^^
76 ]}
77 Action needed: Custom parsing to find and remove the entire field
78 assignment "unbound = 3" (not just "unbound") to maintain valid syntax
79 }
80 }
81
82 {2 Summary of location handling}
83
84 | Warning Type | Location Points To | Additional Processing Needed |
85 |--------------|-------------------|------------------------------| |
86 Warning 32 | Identifier only | Merlin enclosing for full binding | | Warning
87 33 | Full statement | None (direct removal) | | Warning 34 | Full definition
88 | None (direct removal) | | Warning 69 | Full field def | None
89 (character-level removal) | | Sig mismatch | Full declaration | None for
90 .mli files | | Unbound field| Field name only | Custom parsing for field
91 assignment | *)
92
93open Types
94
95val parse : string -> warning_info list
96(** [parse output] parses all warning 32/34 messages from build output. *)