Skip to content

Commit ecbf9ee

Browse files
committed
allow filtering actions, and add test for removing unused var entirely
1 parent efe0489 commit ecbf9ee

File tree

7 files changed

+92
-11
lines changed

7 files changed

+92
-11
lines changed

tests/build_tests/actions/expected/Actions_PrefixUnusedVarUnderscore_applied.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// actionFilter=PrefixVariableWithUnderscore
12
let f = () => {
23
let _x = 1
34
12
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// actionFilter=RemoveUnusedVariable
2+
let f = () => {
3+
12
4+
}

tests/build_tests/actions/fixtures/Actions_PrefixUnusedVarUnderscore.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// actionFilter=PrefixVariableWithUnderscore
12
let f = () => {
23
let x = 1
34
12
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// actionFilter=RemoveUnusedVariable
2+
let f = () => {
3+
let x = 1
4+
12
5+
}

tests/build_tests/actions/input.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ for (const fileName of fixtures) {
3535
const fullFilePath = path.join(import.meta.dirname, "fixtures", fileName);
3636
const cmtPath = fullFilePath.replace(".res", ".cmt");
3737
await bsc([...prefix, "-color", "always", fullFilePath]);
38-
const { stdout, stderr } = await rescriptTools("actions", [
39-
fullFilePath,
40-
cmtPath,
41-
"--runAll",
42-
]);
38+
const firstLine =
39+
(await fs.readFile(fullFilePath, "utf-8")).split("\n")[0] ?? "";
40+
const actionFilter = firstLine.split("actionFilter=")[1];
41+
const callArgs = [fullFilePath, cmtPath, "--runAll"];
42+
if (actionFilter != null) {
43+
callArgs.push("--actionFilter", actionFilter);
44+
}
45+
const { stdout, stderr } = await rescriptTools("actions", callArgs);
4346
if (stderr.length > 0) {
4447
console.error(stderr.toString());
4548
}

tools/bin/main.ml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,25 @@ let main () =
111111
Reanalyze.cli ()
112112
| "actions" :: file :: opts ->
113113
let run_all_on_file = List.mem "--runAll" opts in
114+
let rec extract_arg_with_value target_arg opts =
115+
match opts with
116+
| arg :: value :: _ when arg = target_arg -> Some value
117+
| _ :: rest -> extract_arg_with_value target_arg rest
118+
| [] -> None
119+
in
114120
let cmtPath =
115121
match opts with
116122
| path :: _ when String.ends_with ~suffix:".cmt" path -> Some path
117123
| _ -> None
118124
in
119-
if run_all_on_file then Tools.Actions.runActionsOnFile ?cmtPath file
125+
let actionFilter =
126+
match extract_arg_with_value "--actionFilter" opts with
127+
| Some filter ->
128+
Some (String.split_on_char ',' filter |> List.map String.trim)
129+
| None -> None
130+
in
131+
if run_all_on_file then
132+
Tools.Actions.runActionsOnFile ?actionFilter ?cmtPath file
120133
else Tools.Actions.extractActionsFromFile ?cmtPath file
121134
| "extract-embedded" :: extPointNames :: filename :: _ ->
122135
logAndExit

tools/src/tools.ml

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,23 @@ module Actions = struct
13211321
Ast_mapper.default_mapper.structure mapper items);
13221322
value_bindings =
13231323
(fun mapper bindings ->
1324-
(* TODO: Implement removing binding action *)
1324+
let remove_unused_variables_action_locs =
1325+
List.filter_map
1326+
(fun (action : Cmt_utils.cmt_action) ->
1327+
match action.action with
1328+
| RemoveUnusedVariable -> Some action.loc
1329+
| _ -> None)
1330+
actions
1331+
in
1332+
let bindings =
1333+
bindings
1334+
|> List.filter_map (fun (binding : Parsetree.value_binding) ->
1335+
if
1336+
List.mem binding.pvb_pat.ppat_loc
1337+
remove_unused_variables_action_locs
1338+
then None
1339+
else Some binding)
1340+
in
13251341
Ast_mapper.default_mapper.value_bindings mapper bindings);
13261342
pat =
13271343
(fun mapper pattern ->
@@ -1492,9 +1508,20 @@ module Actions = struct
14921508
}
14931509
| _ -> None)
14941510
in
1511+
let mapped_expr =
1512+
match mapped_expr with
1513+
| None -> Ast_mapper.default_mapper.expr mapper expr
1514+
| Some expr -> expr
1515+
in
1516+
(* We sometimes need to do some post-transformation cleanup.
1517+
E.g if all let bindings was removed from `Pexp_let`, we need to remove the entire Pexp_let.*)
14951518
match mapped_expr with
1496-
| None -> Ast_mapper.default_mapper.expr mapper expr
1497-
| Some expr -> expr);
1519+
| {pexp_desc = Pexp_let (_, [], cont); pexp_attributes} ->
1520+
{
1521+
cont with
1522+
pexp_attributes = cont.pexp_attributes @ pexp_attributes;
1523+
}
1524+
| _ -> mapped_expr);
14981525
}
14991526
in
15001527
if Filename.check_suffix path ".res" then
@@ -1511,7 +1538,8 @@ module Actions = struct
15111538
"error: failed to apply actions to %s because it is not a .res file"
15121539
path)
15131540

1514-
let runActionsOnFile ?cmtPath entryPointFile =
1541+
let runActionsOnFile ?(actionFilter : string list option) ?cmtPath
1542+
entryPointFile =
15151543
let path =
15161544
match Filename.is_relative entryPointFile with
15171545
| true -> Unix.realpath entryPointFile
@@ -1529,7 +1557,33 @@ module Actions = struct
15291557
be found. try to build the project"
15301558
path
15311559
| Some {cmt_possible_actions} -> (
1532-
match applyActionsToFile path cmt_possible_actions with
1560+
let possible_actions =
1561+
match actionFilter with
1562+
| None -> cmt_possible_actions
1563+
| Some filter ->
1564+
cmt_possible_actions
1565+
|> List.filter (fun (action : Cmt_utils.cmt_action) ->
1566+
match action.action with
1567+
| Cmt_utils.ApplyFunction _ -> List.mem "ApplyFunction" filter
1568+
| ApplyCoercion _ -> List.mem "ApplyCoercion" filter
1569+
| RemoveSwitchCase -> List.mem "RemoveSwitchCase" filter
1570+
| RemoveOpen -> List.mem "RemoveOpen" filter
1571+
| RemoveAwait -> List.mem "RemoveAwait" filter
1572+
| AddAwait -> List.mem "AddAwait" filter
1573+
| ReplaceWithVariantConstructor _ ->
1574+
List.mem "ReplaceWithVariantConstructor" filter
1575+
| ReplaceWithPolymorphicVariantConstructor _ ->
1576+
List.mem "ReplaceWithPolymorphicVariantConstructor" filter
1577+
| RewriteObjectToRecord ->
1578+
List.mem "RewriteObjectToRecord" filter
1579+
| RewriteArrayToTuple -> List.mem "RewriteArrayToTuple" filter
1580+
| RewriteIdent _ -> List.mem "RewriteIdent" filter
1581+
| PrefixVariableWithUnderscore ->
1582+
List.mem "PrefixVariableWithUnderscore" filter
1583+
| RemoveUnusedVariable ->
1584+
List.mem "RemoveUnusedVariable" filter)
1585+
in
1586+
match applyActionsToFile path possible_actions with
15331587
| Ok applied -> print_endline applied
15341588
| Error e ->
15351589
print_endline e;

0 commit comments

Comments
 (0)