@@ -304,11 +304,13 @@ module Transform = struct
304
304
in
305
305
{ t with impl = Some map_impl; intf = Some map_intf }
306
306
307
+ let builtin_context_free_name = " <builtin:context-free>"
308
+
307
309
let builtin_of_context_free_rewriters ~hook ~rules ~enclose_impl ~enclose_intf
308
310
~input_name =
309
311
merge_into_generic_mappers ~hook ~input_name
310
312
{
311
- name = " <builtin:context-free> " ;
313
+ name = builtin_context_free_name ;
312
314
aliases = [] ;
313
315
impl = None ;
314
316
intf = None ;
@@ -323,6 +325,21 @@ module Transform = struct
323
325
registered_at = Caller_id. get ~skip: [] ;
324
326
}
325
327
328
+ (* Meant to be used after partitioning *)
329
+ let rewrites_not_context_free t =
330
+ match t with
331
+ | { name; _ } when String. equal name builtin_context_free_name -> false
332
+ | {
333
+ impl = None ;
334
+ intf = None ;
335
+ instrument = None ;
336
+ preprocess_impl = None ;
337
+ preprocess_intf = None ;
338
+ _;
339
+ } ->
340
+ false
341
+ | _ -> true
342
+
326
343
let partition_transformations ts =
327
344
let before_instrs, after_instrs, rest =
328
345
List. fold_left ts ~init: ([] , [] , [] ) ~f: (fun (bef_i , aft_i , rest ) t ->
@@ -528,11 +545,21 @@ let get_whole_ast_passes ~embed_errors ~hook ~expect_mismatch_handler ~tool_name
528
545
linters @ preprocess @ before_instrs @ make_generic cts @ after_instrs
529
546
530
547
let apply_transforms ~tool_name ~file_path ~field ~lint_field ~dropped_so_far
531
- ~hook ~expect_mismatch_handler ~input_name ~embed_errors ast =
548
+ ~hook ~expect_mismatch_handler ~input_name ~embed_errors ?rewritten ast =
549
+ let _ = rewritten in
532
550
let cts =
533
551
get_whole_ast_passes ~tool_name ~embed_errors ~hook ~expect_mismatch_handler
534
552
~input_name
535
553
in
554
+ (match rewritten with
555
+ | None -> ()
556
+ | Some rewritten -> (
557
+ match List. filter cts ~f: Transform. rewrites_not_context_free with
558
+ | [] -> ()
559
+ | _ ->
560
+ (* We won't be able to accurately tell whether any rewriting has
561
+ happened *)
562
+ rewritten := true ));
536
563
let finish (ast , _dropped , lint_errors , errors ) =
537
564
( ast,
538
565
List. map lint_errors ~f: (fun (loc , s ) ->
@@ -633,8 +660,8 @@ let sort_errors_by_loc errors =
633
660
634
661
(* $*)
635
662
636
- let map_structure_gen st ~tool_name ~hook ~expect_mismatch_handler ~input_name
637
- ~embed_errors =
663
+ let map_structure_gen ~tool_name ~hook ~expect_mismatch_handler ~input_name
664
+ ~embed_errors ? rewritten st =
638
665
Cookies. acknowledge_cookies T ;
639
666
if ! perform_checks then (
640
667
Attribute. reset_checks () ;
@@ -693,7 +720,7 @@ let map_structure_gen st ~tool_name ~hook ~expect_mismatch_handler ~input_name
693
720
~field: (fun (ct : Transform.t ) -> ct.impl)
694
721
~lint_field: (fun (ct : Transform.t ) -> ct.lint_impl)
695
722
~dropped_so_far: Attribute. dropped_so_far_structure ~hook
696
- ~expect_mismatch_handler ~input_name ~embed_errors
723
+ ~expect_mismatch_handler ~input_name ~embed_errors ?rewritten
697
724
in
698
725
st |> lint lint_errors |> cookies_and_check |> with_errors (List. rev errors)
699
726
@@ -703,14 +730,14 @@ let map_structure st =
703
730
~tool_name: (Astlib.Ast_metadata. tool_name () )
704
731
~hook: Context_free.Generated_code_hook. nop
705
732
~expect_mismatch_handler: Context_free.Expect_mismatch_handler. nop
706
- ~input_name: None ~embed_errors: false
733
+ ~input_name: None ~embed_errors: false ?rewritten: None
707
734
with
708
735
| ast -> ast
709
736
710
737
(* $ str_to_sig _last_text_block *)
711
738
712
- let map_signature_gen sg ~tool_name ~hook ~expect_mismatch_handler ~input_name
713
- ~embed_errors =
739
+ let map_signature_gen ~tool_name ~hook ~expect_mismatch_handler ~input_name
740
+ ~embed_errors ? rewritten sg =
714
741
Cookies. acknowledge_cookies T ;
715
742
if ! perform_checks then (
716
743
Attribute. reset_checks () ;
@@ -769,7 +796,7 @@ let map_signature_gen sg ~tool_name ~hook ~expect_mismatch_handler ~input_name
769
796
~field: (fun (ct : Transform.t ) -> ct.intf)
770
797
~lint_field: (fun (ct : Transform.t ) -> ct.lint_intf)
771
798
~dropped_so_far: Attribute. dropped_so_far_signature ~hook
772
- ~expect_mismatch_handler ~input_name ~embed_errors
799
+ ~expect_mismatch_handler ~input_name ~embed_errors ?rewritten
773
800
in
774
801
sg |> lint lint_errors |> cookies_and_check |> with_errors (List. rev errors)
775
802
@@ -779,7 +806,7 @@ let map_signature sg =
779
806
~tool_name: (Astlib.Ast_metadata. tool_name () )
780
807
~hook: Context_free.Generated_code_hook. nop
781
808
~expect_mismatch_handler: Context_free.Expect_mismatch_handler. nop
782
- ~input_name: None ~embed_errors: false
809
+ ~input_name: None ~embed_errors: false ?rewritten: None
783
810
with
784
811
| ast -> ast
785
812
@@ -917,6 +944,7 @@ type output_mode =
917
944
| Dparsetree
918
945
| Reconcile of Reconcile .mode
919
946
| Null
947
+ | Dune_optional_output
920
948
921
949
(* $*)
922
950
let extract_cookies_str st =
@@ -1036,14 +1064,14 @@ struct
1036
1064
let set x = t.data < - Some x
1037
1065
end
1038
1066
1039
- let process_ast ( ast : Intf_or_impl.t ) ~input_name ~tool_name ~hook
1040
- ~expect_mismatch_handler ~ embed_errors =
1067
+ let process_ast ~input_name ~tool_name ~hook ~ expect_mismatch_handler
1068
+ ~embed_errors ? rewritten ( ast : Intf_or_impl.t ) =
1041
1069
match ast with
1042
1070
| Intf x ->
1043
1071
let ast =
1044
1072
match
1045
1073
map_signature_gen x ~tool_name ~hook ~expect_mismatch_handler
1046
- ~input_name: (Some input_name) ~embed_errors
1074
+ ~input_name: (Some input_name) ~embed_errors ?rewritten
1047
1075
with
1048
1076
| ast -> ast
1049
1077
in
@@ -1052,18 +1080,28 @@ let process_ast (ast : Intf_or_impl.t) ~input_name ~tool_name ~hook
1052
1080
let ast =
1053
1081
match
1054
1082
map_structure_gen x ~tool_name ~hook ~expect_mismatch_handler
1055
- ~input_name: (Some input_name) ~embed_errors
1083
+ ~input_name: (Some input_name) ~embed_errors ?rewritten
1056
1084
with
1057
1085
| ast -> ast
1058
1086
in
1059
1087
Intf_or_impl. Impl ast
1060
1088
1089
+ let pp_ast ~output (ast : Intf_or_impl.t ) =
1090
+ with_output output ~binary: false ~f: (fun oc ->
1091
+ let ppf = Stdlib.Format. formatter_of_out_channel oc in
1092
+ (match ast with
1093
+ | Intf ast -> Pprintast. signature ppf ast
1094
+ | Impl ast -> Pprintast. structure ppf ast);
1095
+ let null_ast = match ast with Intf [] | Impl [] -> true | _ -> false in
1096
+ if not null_ast then Stdlib.Format. pp_print_newline ppf () )
1097
+
1061
1098
let process_file (kind : Kind.t ) fn ~input_name ~relocate ~output_mode
1062
1099
~embed_errors ~output =
1063
1100
File_property. reset_all () ;
1064
1101
List. iter (List. rev ! process_file_hooks) ~f: (fun f -> f () );
1065
1102
corrections := [] ;
1066
1103
let replacements = ref [] in
1104
+ let rewritten = ref false in
1067
1105
let tool_name = " ppx_driver" in
1068
1106
let hook : Context_free.Generated_code_hook.t =
1069
1107
match output_mode with
@@ -1075,6 +1113,7 @@ let process_file (kind : Kind.t) fn ~input_name ~relocate ~output_mode
1075
1113
(Reconcile.Replacement. make () ~context: (Extension context)
1076
1114
~start: loc.loc_start ~stop: loc.loc_end ~repl: generated));
1077
1115
}
1116
+ | Dune_optional_output -> { f = (fun _ _ _ -> rewritten := true ) }
1078
1117
| _ -> Context_free.Generated_code_hook. nop
1079
1118
in
1080
1119
let expect_mismatch_handler : Context_free.Expect_mismatch_handler.t =
@@ -1097,7 +1136,7 @@ let process_file (kind : Kind.t) fn ~input_name ~relocate ~output_mode
1097
1136
let ast =
1098
1137
extract_cookies ast
1099
1138
|> process_ast ~input_name ~tool_name ~hook ~expect_mismatch_handler
1100
- ~embed_errors
1139
+ ~embed_errors ~rewritten
1101
1140
in
1102
1141
(input_fname, input_version, ast)
1103
1142
with exn when embed_errors ->
@@ -1134,16 +1173,8 @@ let process_file (kind : Kind.t) fn ~input_name ~relocate ~output_mode
1134
1173
1135
1174
(match output_mode with
1136
1175
| Null -> ()
1137
- | Pretty_print ->
1138
- with_output output ~binary: false ~f: (fun oc ->
1139
- let ppf = Stdlib.Format. formatter_of_out_channel oc in
1140
- (match ast with
1141
- | Intf ast -> Pprintast. signature ppf ast
1142
- | Impl ast -> Pprintast. structure ppf ast);
1143
- let null_ast =
1144
- match ast with Intf [] | Impl [] -> true | _ -> false
1145
- in
1146
- if not null_ast then Stdlib.Format. pp_print_newline ppf () )
1176
+ | Pretty_print -> pp_ast ~output ast
1177
+ | Dune_optional_output -> if ! rewritten then pp_ast ~output ast
1147
1178
| Dump_ast ->
1148
1179
with_output output ~binary: true ~f: (fun oc ->
1149
1180
Ast_io. write oc
@@ -1191,7 +1222,10 @@ let set_output_mode mode =
1191
1222
match (! output_mode, mode) with
1192
1223
| Pretty_print , _ -> output_mode := mode
1193
1224
| _ , Pretty_print -> assert false
1194
- | Dump_ast , Dump_ast | Dparsetree , Dparsetree -> ()
1225
+ | Dune_optional_output , Dune_optional_output
1226
+ | Dump_ast , Dump_ast
1227
+ | Dparsetree , Dparsetree ->
1228
+ ()
1195
1229
| Reconcile a , Reconcile b when Poly. equal a b -> ()
1196
1230
| x , y ->
1197
1231
let arg_of_output_mode = function
@@ -1201,6 +1235,7 @@ let set_output_mode mode =
1201
1235
| Reconcile Using_line_directives -> " -reconcile"
1202
1236
| Reconcile Delimiting_generated_blocks -> " -reconcile-with-comments"
1203
1237
| Null -> " -null"
1238
+ | Dune_optional_output -> " -dune-optional-output"
1204
1239
in
1205
1240
raise
1206
1241
(Arg. Bad
@@ -1409,6 +1444,9 @@ let standalone_args =
1409
1444
( " -corrected-suffix" ,
1410
1445
Arg. Set_string corrected_suffix,
1411
1446
" SUFFIX Suffix to append to corrected files" );
1447
+ ( " -dune-optional-output" ,
1448
+ Arg. Unit (fun () -> set_output_mode Dune_optional_output ),
1449
+ " For dune's internal use only" );
1412
1450
]
1413
1451
1414
1452
let get_args ?(standalone_args = standalone_args) () =
0 commit comments