Skip to content

Commit

Permalink
fix: keep menhir .conflicts files (ocaml#6865)
Browse files Browse the repository at this point in the history
Add the .conflicts file to targets of menhir stanzas when the
--explain flag is present and menhir is not called with --only-tokens.
  • Loading branch information
Tchou committed Oct 27, 2023
1 parent dd8b9d6 commit a210113
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions src/dune_rules/menhir/menhir_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ module Run (P : PARAMS) = struct

let source m = Path.relative (Path.build dir) (m ^ ".mly")

let targets m ~cmly =
let targets m ~cmly ~conflicts =
let base = [ m ^ ".ml"; m ^ ".mli" ] in
let base = if conflicts then (m ^ ".conflicts") :: base else base in
List.map ~f:(Path.Build.relative dir) (if cmly then (m ^ ".cmly") :: base else base)
;;

Expand Down Expand Up @@ -185,7 +186,7 @@ module Run (P : PARAMS) = struct
is the three-step process where Menhir is invoked twice and OCaml type
inference is performed in between. *)

let process3 base ~cmly (stanza : stanza) : unit Memo.t =
let process3 base ~cmly ~conflicts (stanza : stanza) : unit Memo.t =
let open Memo.O in
let expanded_flags = expand_flags stanza.flags in
(* 1. A first invocation of Menhir creates a mock [.ml] file. *)
Expand Down Expand Up @@ -234,7 +235,7 @@ module Run (P : PARAMS) = struct
; Path (Path.relative (Path.build dir) base)
; A "--infer-read-reply"
; Dep (Path.build (inferred_mli base))
; Hidden_targets (targets base ~cmly)
; Hidden_targets (targets base ~cmly ~conflicts)
]
>>= rule
;;
Expand All @@ -244,15 +245,15 @@ module Run (P : PARAMS) = struct
(* [process3 stanza] converts a Menhir stanza into a set of build rules. This
is a simpler one-step process where Menhir is invoked directly. *)

let process1 base ~cmly (stanza : stanza) : unit Memo.t =
let process1 base ~cmly ~conflicts (stanza : stanza) : unit Memo.t =
let open Memo.O in
let expanded_flags = expand_flags stanza.flags in
menhir
[ Command.Args.dyn expanded_flags
; Deps (sources stanza.modules)
; A "--base"
; Path (Path.relative (Path.build dir) base)
; Hidden_targets (targets base ~cmly)
; Hidden_targets (targets base ~cmly ~conflicts)
]
>>= rule
;;
Expand All @@ -263,26 +264,32 @@ module Run (P : PARAMS) = struct
either [process3] or [process1], as appropriate. *)

(* Because Menhir processes [--only-tokens] before the [--infer-*] commands,
when [--only-tokens] is present, no [--infer-*] command should be used. *)
when [--only-tokens] is present, no [--infer-*] command should be used.
When Menhir is called with [--only-tokens], it does not generate a [.conflicts]
file even the [--explain] flag is passed. Otherwise, a (possibly empty)
[.conflicts] file is always generated (if Menhir succeeds in creating a
[.ml/.mli] file).
*)

let process (stanza : stanza) : unit Memo.t =
let base = Option.value_exn stanza.merge_into in
let ocaml_type_inference_disabled, cmly =
let ocaml_type_inference_disabled, cmly, conflicts =
Ordered_set_lang.Unexpanded.fold_strings
stanza.flags
~init:(false, false)
~f:(fun pos sw ((only_tokens, cmly) as acc) ->
~init:(false, false, false)
~f:(fun pos sw ((only_tokens, cmly, conflicts) as acc) ->
match pos with
| Neg -> acc
| Pos ->
(match String_with_vars.text_only sw with
| Some "--only-tokens" -> true, cmly
| Some "--cmly" -> only_tokens, true
| Some "--only-tokens" -> true, cmly, false
| Some "--cmly" -> only_tokens, true, conflicts
| Some "--explain" -> only_tokens, cmly, not only_tokens
| Some _ | None -> acc))
in
if ocaml_type_inference_disabled || not stanza.infer
then process1 base stanza ~cmly
else process3 base stanza ~cmly
then process1 base stanza ~cmly ~conflicts
else process3 base stanza ~cmly ~conflicts
;;

(* ------------------------------------------------------------------------ *)
Expand Down

0 comments on commit a210113

Please sign in to comment.