From 67edb7f89e0fd6d108649b32a2a3c8d2d186d97c Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 15:19:54 +0700 Subject: [PATCH 01/19] Move make_loc to Loc module and rename it to of_lexbuf Signed-off-by: Rudi Grinberg --- src/usexp/loc.ml | 5 +++++ src/usexp/loc.mli | 2 ++ src/usexp/usexp.ml | 19 +++++++------------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/usexp/loc.ml b/src/usexp/loc.ml index d7ac4844..54c9aeac 100644 --- a/src/usexp/loc.ml +++ b/src/usexp/loc.ml @@ -16,3 +16,8 @@ let in_file fn = } let none = in_file "" + +let of_lexbuf lexbuf : t = + { start = Lexing.lexeme_start_p lexbuf + ; stop = Lexing.lexeme_end_p lexbuf + } diff --git a/src/usexp/loc.mli b/src/usexp/loc.mli index 514f3a68..2526948e 100644 --- a/src/usexp/loc.mli +++ b/src/usexp/loc.mli @@ -6,3 +6,5 @@ type t = val in_file : string -> t val none : t + +val of_lexbuf : Lexing.lexbuf -> t diff --git a/src/usexp/usexp.ml b/src/usexp/usexp.ml index 3681098a..b687686e 100644 --- a/src/usexp/usexp.ml +++ b/src/usexp/usexp.ml @@ -166,11 +166,6 @@ module Parser = struct ; message }) - let make_loc lexbuf : Loc.t = - { start = Lexing.lexeme_start_p lexbuf - ; stop = Lexing.lexeme_end_p lexbuf - } - module Mode = struct type 'a t = | Single : Ast.t t @@ -183,7 +178,7 @@ module Parser = struct | Single -> begin match sexps with | [sexp] -> sexp - | [] -> error (make_loc lexbuf) "no s-expression found in input" + | [] -> error (Loc.of_lexbuf lexbuf) "no s-expression found in input" | _ :: sexp :: _ -> error (Ast.loc sexp) "too many s-expressions found in input" end @@ -200,13 +195,13 @@ module Parser = struct let rec loop depth lexer lexbuf acc = match (lexer lexbuf : Lexer.Token.t) with | Atom a -> - let loc = make_loc lexbuf in + let loc = Loc.of_lexbuf lexbuf in loop depth lexer lexbuf (Ast.Atom (loc, a) :: acc) | Quoted_string s -> - let loc = make_loc lexbuf in + let loc = Loc.of_lexbuf lexbuf in loop depth lexer lexbuf (Quoted_string (loc, s) :: acc) | Template t -> - let loc = make_loc lexbuf in + let loc = Loc.of_lexbuf lexbuf in loop depth lexer lexbuf (Template { t with loc } :: acc) | Lparen -> let start = Lexing.lexeme_start_p lexbuf in @@ -215,12 +210,12 @@ module Parser = struct loop depth lexer lexbuf (List ({ start; stop }, sexps) :: acc) | Rparen -> if depth = 0 then - error (make_loc lexbuf) + error (Loc.of_lexbuf lexbuf) "right parenthesis without matching left parenthesis"; List.rev acc | Sexp_comment -> let sexps = - let loc = make_loc lexbuf in + let loc = Loc.of_lexbuf lexbuf in match loop depth lexer lexbuf [] with | _ :: sexps -> sexps | [] -> error loc "s-expression missing after #;" @@ -228,7 +223,7 @@ module Parser = struct List.rev_append acc sexps | Eof -> if depth > 0 then - error (make_loc lexbuf) + error (Loc.of_lexbuf lexbuf) "unclosed parenthesis at end of input"; List.rev acc From 179d23ee3872b792e1db6af4a13612622909be35 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 15:20:12 +0700 Subject: [PATCH 02/19] Expose the type of tokens and lexers This will be necessary for some manual parsing Signed-off-by: Rudi Grinberg --- src/usexp/usexp.mli | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/usexp/usexp.mli b/src/usexp/usexp.mli index f6c55388..bc0ad768 100644 --- a/src/usexp/usexp.mli +++ b/src/usexp/usexp.mli @@ -28,6 +28,8 @@ module Loc : sig val in_file : string -> t val none : t + + val of_lexbuf : Lexing.lexbuf -> t end module Template : sig @@ -112,7 +114,18 @@ end exception Parse_error of Parse_error.t module Lexer : sig - type t + module Token : sig + type t = + | Atom of Atom.t + | Quoted_string of string + | Lparen + | Rparen + | Sexp_comment + | Eof + | Template of Template.t + end + + type t = Lexing.lexbuf -> Token.t val token : t val jbuild_token : t From c906801c69654a247d690d5aee0c6ed9177666ee Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 15:20:40 +0700 Subject: [PATCH 03/19] Parse dune files in a versioned way. We read the first 3 tokens of a dune file and use it recognize if the file was generated using jbuilder or dune Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index ab7535cc..3fc1d3c2 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -45,7 +45,36 @@ let of_sexp = ] let load fname = - Sexp.Of_sexp.parse of_sexp Univ_map.empty (Io.Sexp.load ~mode:Single fname) + Io.with_lexbuf_from_file fname ~f:(fun lexbuf -> + let (version_loc, version) = + let bad_dune_file = "Unable to read (dune x.y ..) line file" in + let rec loop = function + | [_; _; _] as a -> List.rev a + | acc -> + begin match (Sexp.Lexer.token lexbuf : Sexp.Lexer.Token.t) with + | Eof -> + Loc.fail (Loc.in_file (Path.to_string fname)) "%s" bad_dune_file + | t -> loop (t :: acc) + end + in + match loop [] with + | [Lparen; Atom (A "dune"); Atom s] -> + (Sexp.Loc.of_lexbuf lexbuf, Sexp.Atom.to_string s) + | _ -> + Loc.fail + { start = Lexing.lexeme_start_p lexbuf + ; stop = Lexing.lexeme_end_p lexbuf + } "%s" bad_dune_file + in + match version with + | "1" -> + Sexp.Of_sexp.parse of_sexp Univ_map.empty + (Io.Sexp.load ~lexer:Sexp.Lexer.jbuild_token ~mode:Single fname) + | "2" -> + Sexp.Of_sexp.parse of_sexp Univ_map.empty + (Io.Sexp.load ~lexer:Sexp.Lexer.token ~mode:Single fname) + | _ -> + Loc.fail version_loc "unknown version %S" version) let gen confs = let sexps = From a4bc2602410c1dfa8516b89ab9a6975d2b6c3575 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 16:56:19 +0700 Subject: [PATCH 04/19] Loc.of_lexbuf Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 3fc1d3c2..1940b5ed 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -61,10 +61,7 @@ let load fname = | [Lparen; Atom (A "dune"); Atom s] -> (Sexp.Loc.of_lexbuf lexbuf, Sexp.Atom.to_string s) | _ -> - Loc.fail - { start = Lexing.lexeme_start_p lexbuf - ; stop = Lexing.lexeme_end_p lexbuf - } "%s" bad_dune_file + Loc.fail (Sexp.Loc.of_lexbuf lexbuf) "%s" bad_dune_file in match version with | "1" -> From 8390af90e4018bd479ccc5228689d109499daf96 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 17:00:02 +0700 Subject: [PATCH 05/19] Simplify versioning matching Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 1940b5ed..8c9b98e7 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -63,15 +63,13 @@ let load fname = | _ -> Loc.fail (Sexp.Loc.of_lexbuf lexbuf) "%s" bad_dune_file in - match version with - | "1" -> - Sexp.Of_sexp.parse of_sexp Univ_map.empty - (Io.Sexp.load ~lexer:Sexp.Lexer.jbuild_token ~mode:Single fname) - | "2" -> - Sexp.Of_sexp.parse of_sexp Univ_map.empty - (Io.Sexp.load ~lexer:Sexp.Lexer.token ~mode:Single fname) - | _ -> - Loc.fail version_loc "unknown version %S" version) + let lexer = + match version with + | "1" -> Sexp.Lexer.jbuild_token + | "2" -> Sexp.Lexer.token + | _ -> Loc.fail version_loc "unknown version %S" version + in + Sexp.Of_sexp.parse of_sexp Univ_map.empty lexer ~mode:Single fname let gen confs = let sexps = From bedad1f6898da158054d687ca84b3ef8fa608fa8 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 17:08:15 +0700 Subject: [PATCH 06/19] Set version when parsing dune files Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 8c9b98e7..a1afb4a6 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -63,13 +63,15 @@ let load fname = | _ -> Loc.fail (Sexp.Loc.of_lexbuf lexbuf) "%s" bad_dune_file in - let lexer = + let (lexer, syntax) = match version with - | "1" -> Sexp.Lexer.jbuild_token - | "2" -> Sexp.Lexer.token + | "1" -> (Sexp.Lexer.jbuild_token, (0, 0)) + | "2" -> (Sexp.Lexer.token, (1, 0)) | _ -> Loc.fail version_loc "unknown version %S" version in - Sexp.Of_sexp.parse of_sexp Univ_map.empty lexer ~mode:Single fname + Sexp.Of_sexp.parse of_sexp + (Univ_map.singleton (Syntax.key Stanza.syntax) syntax) + (Io.Sexp.load ~lexer ~mode:Single fname)) let gen confs = let sexps = From 7b12e12571f344a93e731c236a826a6d65a7e0ca Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 17:09:27 +0700 Subject: [PATCH 07/19] Share loc variable Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index a1afb4a6..803a4918 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -57,11 +57,10 @@ let load fname = | t -> loop (t :: acc) end in + let loc = Sexp.Loc.of_lexbuf lexbuf in match loop [] with - | [Lparen; Atom (A "dune"); Atom s] -> - (Sexp.Loc.of_lexbuf lexbuf, Sexp.Atom.to_string s) - | _ -> - Loc.fail (Sexp.Loc.of_lexbuf lexbuf) "%s" bad_dune_file + | [Lparen; Atom (A "dune"); Atom s] -> (loc, Sexp.Atom.to_string s) + | _ -> Loc.fail loc "%s" bad_dune_file in let (lexer, syntax) = match version with From ba9335badf0f43f9c788571221d798ad69c5e443 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 17:32:05 +0700 Subject: [PATCH 08/19] Simplify dump_config with Option.map Signed-off-by: Rudi Grinberg --- src/lib.ml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index 71f584d6..5a2a3920 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -508,9 +508,7 @@ module Sub_system = struct let dump_config lib = Sub_system_name.Map.filter_map lib.sub_systems ~f:(fun (lazy inst) -> let (Sub_system0.Instance.T ((module M), t)) = inst in - match M.to_sexp with - | None -> None - | Some f -> Some (f t)) + Option.map ~f:(fun f -> f t) M.to_sexp) end (* +-----------------------------------------------------------------+ From 9c0daa24defa2e488b60d84530b42f420b6182f0 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 23:00:17 +0700 Subject: [PATCH 09/19] Don't hard code parsing_context for sub systems Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 803a4918..422f20fc 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -1,6 +1,6 @@ open Import -let parse_sub_systems sexps = +let parse_sub_systems ~parsing_context sexps = List.filter_map sexps ~f:(fun sexp -> let name, ver, data = Sexp.Of_sexp.(parse (triple string (located Syntax.Version.t) raw) @@ -21,11 +21,6 @@ let parse_sub_systems sexps = |> Sub_system_name.Map.mapi ~f:(fun name (_, version, data) -> let (module M) = Jbuild.Sub_system_info.get name in Syntax.check_supported M.syntax version; - let parsing_context = - Univ_map.singleton (Syntax.key M.syntax) - (* This is wrong, see #909 *) - (0, 0) - in M.T (Sexp.Of_sexp.parse M.parse parsing_context data)) let of_sexp = @@ -40,8 +35,9 @@ let of_sexp = sum [ "dune", (version >>= fun () -> - list raw >>| fun l -> - parse_sub_systems l) + get_all >>= fun parsing_context -> + list raw >>| + parse_sub_systems ~parsing_context) ] let load fname = From f6fe5d20bbe4d6c9c008433ffb2c8065e4917279 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 1 Jul 2018 23:18:36 +0700 Subject: [PATCH 10/19] Generate dune file version correctly Signed-off-by: Rudi Grinberg --- src/install_rules.ml | 3 ++- src/installed_dune_file.ml | 13 ++++++++----- src/installed_dune_file.mli | 5 ++++- src/lib.ml | 11 +++++++++++ src/lib.mli | 3 +++ test/blackbox-tests/test-cases/inline_tests/run.t | 2 +- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/install_rules.ml b/src/install_rules.ml index 3c679e40..6b8b763d 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -39,8 +39,9 @@ module Gen(P : Install_params) = struct let gen_lib_dune_file lib = SC.add_rule sctx (Build.arr (fun () -> + let lang = Option.value_exn (Lib.defined_using_lang lib) in Format.asprintf "%a@." (Sexp.pp Dune) - (Lib.Sub_system.dump_config lib |> Installed_dune_file.gen)) + (Lib.Sub_system.dump_config lib |> Installed_dune_file.gen ~lang)) >>> Build.write_file_dyn (lib_dune_file ~dir:(Lib.src_dir lib) ~name:(Lib.name lib))) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 422f20fc..b3abe8d6 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -27,10 +27,10 @@ let of_sexp = let open Sexp.Of_sexp in let version = plain_string (fun ~loc -> function - | "1" -> () - | _ -> + | "1" | "2" -> () + | v -> of_sexp_errorf loc - "Unsupported version, only version 1 is supported") + "Unsupported version %S, only version 1 is supported" v) in sum [ "dune", @@ -68,7 +68,7 @@ let load fname = (Univ_map.singleton (Syntax.key Stanza.syntax) syntax) (Io.Sexp.load ~lexer ~mode:Single fname)) -let gen confs = +let gen ~(lang : File_tree.Dune_file.Kind.t) confs = let sexps = Sub_system_name.Map.to_list confs |> List.map ~f:(fun (name, (ver, conf)) -> @@ -80,6 +80,9 @@ let gen confs = in Sexp.List [ Sexp.unsafe_atom_of_string "dune" - ; Sexp.unsafe_atom_of_string "1" + ; Sexp.unsafe_atom_of_string + (match lang with + | Jbuild -> "1" + | Dune -> "2") ; List sexps ] diff --git a/src/installed_dune_file.mli b/src/installed_dune_file.mli index d498cb00..019e5c88 100644 --- a/src/installed_dune_file.mli +++ b/src/installed_dune_file.mli @@ -3,4 +3,7 @@ open Stdune val load : Path.t -> Jbuild.Sub_system_info.t Sub_system_name.Map.t -val gen : (Syntax.Version.t * Sexp.t) Sub_system_name.Map.t -> Sexp.t +val gen + : lang:File_tree.Dune_file.Kind.t + -> (Syntax.Version.t * Sexp.t) Sub_system_name.Map.t + -> Sexp.t diff --git a/src/lib.ml b/src/lib.ml index 5a2a3920..4635a120 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -63,6 +63,7 @@ module Info = struct ; pps : (Loc.t * Jbuild.Pp.t) list ; optional : bool ; virtual_deps : (Loc.t * string) list + ; defined_using_lang : File_tree.Dune_file.Kind.t option ; sub_systems : Jbuild.Sub_system_info.t Sub_system_name.Map.t } @@ -114,6 +115,11 @@ module Info = struct ; ppx_runtime_deps = conf.ppx_runtime_libraries ; pps = Jbuild.Preprocess_map.pps conf.buildable.preprocess ; sub_systems = conf.sub_systems + ; defined_using_lang = + Some + (match conf.project.kind with + | Dune -> Dune + | Jbuilder -> Jbuild) } let of_findlib_package pkg = @@ -143,6 +149,7 @@ module Info = struct ; (* We don't know how these are named for external libraries *) foreign_archives = Mode.Dict.make_both [] ; sub_systems = sub_systems + ; defined_using_lang = None } end @@ -237,6 +244,7 @@ type t = ; resolved_selects : Resolved_select.t list ; optional : bool ; user_written_deps : Jbuild.Lib_deps.t + ; defined_using_lang : File_tree.Dune_file.Kind.t option ; (* This is mutable to avoid this error: {[ @@ -343,6 +351,8 @@ let plugins t = t.plugins let jsoo_runtime t = t.jsoo_runtime let unique_id t = t.unique_id +let defined_using_lang t = t.defined_using_lang + let src_dir t = t.src_dir let obj_dir t = t.obj_dir @@ -662,6 +672,7 @@ let rec instantiate db name (info : Info.t) ~stack ~hidden = ; optional = info.optional ; user_written_deps = Info.user_written_deps info ; sub_systems = Sub_system_name.Map.empty + ; defined_using_lang = info.defined_using_lang } in t.sub_systems <- diff --git a/src/lib.mli b/src/lib.mli index d70ef8c9..795727fb 100644 --- a/src/lib.mli +++ b/src/lib.mli @@ -26,6 +26,8 @@ val archives : t -> Path.t list Mode.Dict.t val plugins : t -> Path.t list Mode.Dict.t val jsoo_runtime : t -> Path.t list +val defined_using_lang : t -> File_tree.Dune_file.Kind.t option + (** A unique integer identifier. It is only unique for the duration of the process *) val unique_id : t -> int @@ -103,6 +105,7 @@ module Info : sig ; pps : (Loc.t * Jbuild.Pp.t) list ; optional : bool ; virtual_deps : (Loc.t * string) list + ; defined_using_lang : File_tree.Dune_file.Kind.t option ; sub_systems : Jbuild.Sub_system_info.t Sub_system_name.Map.t } diff --git a/test/blackbox-tests/test-cases/inline_tests/run.t b/test/blackbox-tests/test-cases/inline_tests/run.t index 3646e4ae..d46693c7 100644 --- a/test/blackbox-tests/test-cases/inline_tests/run.t +++ b/test/blackbox-tests/test-cases/inline_tests/run.t @@ -22,7 +22,7 @@ $ dune runtest dune-file (dune - 1 + 2 ((inline_tests.backend 1.0 ((runner_libraries (str)) From 01163776ad3b5e2c20e9a6c9c5963b90d38dd121 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 13:09:10 +0700 Subject: [PATCH 11/19] s/Dune/lang/ Signed-off-by: Rudi Grinberg --- src/install_rules.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/install_rules.ml b/src/install_rules.ml index 6b8b763d..fb87fb98 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -40,7 +40,7 @@ module Gen(P : Install_params) = struct SC.add_rule sctx (Build.arr (fun () -> let lang = Option.value_exn (Lib.defined_using_lang lib) in - Format.asprintf "%a@." (Sexp.pp Dune) + Format.asprintf "%a@." (Sexp.pp lang) (Lib.Sub_system.dump_config lib |> Installed_dune_file.gen ~lang)) >>> Build.write_file_dyn (lib_dune_file ~dir:(Lib.src_dir lib) ~name:(Lib.name lib))) From 9005ca899862b2c91ea627426772dedaa83d7f74 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 13:34:14 +0700 Subject: [PATCH 12/19] Simplify error handling Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index b3abe8d6..45ace65f 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -43,20 +43,18 @@ let of_sexp = let load fname = Io.with_lexbuf_from_file fname ~f:(fun lexbuf -> let (version_loc, version) = - let bad_dune_file = "Unable to read (dune x.y ..) line file" in let rec loop = function | [_; _; _] as a -> List.rev a | acc -> begin match (Sexp.Lexer.token lexbuf : Sexp.Lexer.Token.t) with - | Eof -> - Loc.fail (Loc.in_file (Path.to_string fname)) "%s" bad_dune_file + | Eof -> List.rev acc | t -> loop (t :: acc) end in let loc = Sexp.Loc.of_lexbuf lexbuf in match loop [] with | [Lparen; Atom (A "dune"); Atom s] -> (loc, Sexp.Atom.to_string s) - | _ -> Loc.fail loc "%s" bad_dune_file + | _ -> Loc.fail loc "Unable to read (dune x.y ..) line file" in let (lexer, syntax) = match version with From 22cf958b0c74edb9694730f827e5dfe0a9cb373e Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 14:08:28 +0700 Subject: [PATCH 13/19] Add dune_version field for libraries This field is necessary to know how to generate .dune files for a particular library. Signed-off-by: Rudi Grinberg --- src/jbuild.ml | 3 +++ src/jbuild.mli | 1 + 2 files changed, 4 insertions(+) diff --git a/src/jbuild.ml b/src/jbuild.ml index 7b460de3..d6d8ef63 100644 --- a/src/jbuild.ml +++ b/src/jbuild.ml @@ -732,6 +732,7 @@ module Library = struct ; project : Dune_project.t ; sub_systems : Sub_system_info.t Sub_system_name.Map.t ; no_keep_locs : bool + ; dune_version : Syntax.Version.t } let t = @@ -763,6 +764,7 @@ module Library = struct field_b "no_keep_locs" >>= fun no_keep_locs -> Sub_system_info.record_parser () >>= fun sub_systems -> Dune_project.get_exn () >>= fun project -> + Syntax.get_exn Stanza.syntax >>= fun dune_version -> return { name ; public @@ -786,6 +788,7 @@ module Library = struct ; project ; sub_systems ; no_keep_locs + ; dune_version }) let has_stubs t = diff --git a/src/jbuild.mli b/src/jbuild.mli index e9048140..82174b7a 100644 --- a/src/jbuild.mli +++ b/src/jbuild.mli @@ -206,6 +206,7 @@ module Library : sig ; project : Dune_project.t ; sub_systems : Sub_system_info.t Sub_system_name.Map.t ; no_keep_locs : bool + ; dune_version : Syntax.Version.t } val has_stubs : t -> bool From 4af1f189f036d2650ce07363169a3dc5e0d439fe Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 14:23:13 +0700 Subject: [PATCH 14/19] Using Syntax.Verison.t to decide how to generate sub system files Signed-off-by: Rudi Grinberg --- src/install_rules.ml | 8 +++++--- src/installed_dune_file.ml | 11 +++++++---- src/installed_dune_file.mli | 2 +- src/lib.ml | 16 ++++++---------- src/lib.mli | 4 ++-- src/stanza.ml | 6 +++++- src/stanza.mli | 4 +++- 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/install_rules.ml b/src/install_rules.ml index fb87fb98..75729b6c 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -39,9 +39,11 @@ module Gen(P : Install_params) = struct let gen_lib_dune_file lib = SC.add_rule sctx (Build.arr (fun () -> - let lang = Option.value_exn (Lib.defined_using_lang lib) in - Format.asprintf "%a@." (Sexp.pp lang) - (Lib.Sub_system.dump_config lib |> Installed_dune_file.gen ~lang)) + let dune_version = Option.value_exn (Lib.dune_version lib) in + Format.asprintf "%a@." + (Sexp.pp (Stanza.File_kind.of_syntax dune_version)) + (Lib.Sub_system.dump_config lib + |> Installed_dune_file.gen ~dune_version)) >>> Build.write_file_dyn (lib_dune_file ~dir:(Lib.src_dir lib) ~name:(Lib.name lib))) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 45ace65f..8e5ee1c9 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -66,7 +66,7 @@ let load fname = (Univ_map.singleton (Syntax.key Stanza.syntax) syntax) (Io.Sexp.load ~lexer ~mode:Single fname)) -let gen ~(lang : File_tree.Dune_file.Kind.t) confs = +let gen ~(dune_version : Syntax.Version.t) confs = let sexps = Sub_system_name.Map.to_list confs |> List.map ~f:(fun (name, (ver, conf)) -> @@ -79,8 +79,11 @@ let gen ~(lang : File_tree.Dune_file.Kind.t) confs = Sexp.List [ Sexp.unsafe_atom_of_string "dune" ; Sexp.unsafe_atom_of_string - (match lang with - | Jbuild -> "1" - | Dune -> "2") + (match dune_version with + | (0, 0) -> "1" + | (1, 0) -> "2" + | _ -> + Exn.code_error "Cannot generate dune with unknown version" + ["dune_version", Syntax.Version.sexp_of_t dune_version]) ; List sexps ] diff --git a/src/installed_dune_file.mli b/src/installed_dune_file.mli index 019e5c88..a82abb8e 100644 --- a/src/installed_dune_file.mli +++ b/src/installed_dune_file.mli @@ -4,6 +4,6 @@ open Stdune val load : Path.t -> Jbuild.Sub_system_info.t Sub_system_name.Map.t val gen - : lang:File_tree.Dune_file.Kind.t + : dune_version:Syntax.Version.t -> (Syntax.Version.t * Sexp.t) Sub_system_name.Map.t -> Sexp.t diff --git a/src/lib.ml b/src/lib.ml index 4635a120..d11f8f67 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -63,7 +63,7 @@ module Info = struct ; pps : (Loc.t * Jbuild.Pp.t) list ; optional : bool ; virtual_deps : (Loc.t * string) list - ; defined_using_lang : File_tree.Dune_file.Kind.t option + ; dune_version : Syntax.Version.t option ; sub_systems : Jbuild.Sub_system_info.t Sub_system_name.Map.t } @@ -115,11 +115,7 @@ module Info = struct ; ppx_runtime_deps = conf.ppx_runtime_libraries ; pps = Jbuild.Preprocess_map.pps conf.buildable.preprocess ; sub_systems = conf.sub_systems - ; defined_using_lang = - Some - (match conf.project.kind with - | Dune -> Dune - | Jbuilder -> Jbuild) + ; dune_version = Some conf.dune_version } let of_findlib_package pkg = @@ -149,7 +145,7 @@ module Info = struct ; (* We don't know how these are named for external libraries *) foreign_archives = Mode.Dict.make_both [] ; sub_systems = sub_systems - ; defined_using_lang = None + ; dune_version = None } end @@ -244,7 +240,7 @@ type t = ; resolved_selects : Resolved_select.t list ; optional : bool ; user_written_deps : Jbuild.Lib_deps.t - ; defined_using_lang : File_tree.Dune_file.Kind.t option + ; dune_version : Syntax.Version.t option ; (* This is mutable to avoid this error: {[ @@ -351,7 +347,7 @@ let plugins t = t.plugins let jsoo_runtime t = t.jsoo_runtime let unique_id t = t.unique_id -let defined_using_lang t = t.defined_using_lang +let dune_version t = t.dune_version let src_dir t = t.src_dir let obj_dir t = t.obj_dir @@ -672,7 +668,7 @@ let rec instantiate db name (info : Info.t) ~stack ~hidden = ; optional = info.optional ; user_written_deps = Info.user_written_deps info ; sub_systems = Sub_system_name.Map.empty - ; defined_using_lang = info.defined_using_lang + ; dune_version = info.dune_version } in t.sub_systems <- diff --git a/src/lib.mli b/src/lib.mli index 795727fb..b50a4a7c 100644 --- a/src/lib.mli +++ b/src/lib.mli @@ -26,7 +26,7 @@ val archives : t -> Path.t list Mode.Dict.t val plugins : t -> Path.t list Mode.Dict.t val jsoo_runtime : t -> Path.t list -val defined_using_lang : t -> File_tree.Dune_file.Kind.t option +val dune_version : t -> Syntax.Version.t option (** A unique integer identifier. It is only unique for the duration of the process *) @@ -105,7 +105,7 @@ module Info : sig ; pps : (Loc.t * Jbuild.Pp.t) list ; optional : bool ; virtual_deps : (Loc.t * string) list - ; defined_using_lang : File_tree.Dune_file.Kind.t option + ; dune_version : Syntax.Version.t option ; sub_systems : Jbuild.Sub_system_info.t Sub_system_name.Map.t } diff --git a/src/stanza.ml b/src/stanza.ml index b6166c8f..898257f2 100644 --- a/src/stanza.ml +++ b/src/stanza.ml @@ -13,7 +13,11 @@ let syntax = ] module File_kind = struct - type t = Jbuild | Dune + type t = Sexp.syntax = Jbuild | Dune + + let of_syntax = function + | (0, 0) -> Jbuild + | (_, _) -> Dune end let file_kind () = diff --git a/src/stanza.mli b/src/stanza.mli index 5377360b..1934f06b 100644 --- a/src/stanza.mli +++ b/src/stanza.mli @@ -18,7 +18,9 @@ end val syntax : Syntax.t module File_kind : sig - type t = Jbuild | Dune + type t = Sexp.syntax = Jbuild | Dune + + val of_syntax : Syntax.Version.t -> t end (** Whether we are parsing a [jbuild] or [dune] file. *) From 0051aeca291e028a2e9dceefcc6a766719c7297c Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 14:42:43 +0700 Subject: [PATCH 15/19] Do not read .dune files twice Reuse the same lexer by pushing back some tokens manually Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 8e5ee1c9..089b108e 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -42,7 +42,7 @@ let of_sexp = let load fname = Io.with_lexbuf_from_file fname ~f:(fun lexbuf -> - let (version_loc, version) = + let (tokens, version_loc, version) = let rec loop = function | [_; _; _] as a -> List.rev a | acc -> @@ -53,7 +53,8 @@ let load fname = in let loc = Sexp.Loc.of_lexbuf lexbuf in match loop [] with - | [Lparen; Atom (A "dune"); Atom s] -> (loc, Sexp.Atom.to_string s) + | [Lparen; Atom (A "dune"); Atom s] as tokens -> + (tokens, loc, Sexp.Atom.to_string s) | _ -> Loc.fail loc "Unable to read (dune x.y ..) line file" in let (lexer, syntax) = @@ -62,9 +63,17 @@ let load fname = | "2" -> (Sexp.Lexer.token, (1, 0)) | _ -> Loc.fail version_loc "unknown version %S" version in + (* push back the tokens that we already read *) + let lexer = + let pending_tokens = ref tokens in + fun lb -> + match !pending_tokens with + | [] -> lexer lb + | x :: xs -> pending_tokens := xs; x + in Sexp.Of_sexp.parse of_sexp (Univ_map.singleton (Syntax.key Stanza.syntax) syntax) - (Io.Sexp.load ~lexer ~mode:Single fname)) + (Sexp.Parser.parse ~lexer ~mode:Single lexbuf)) let gen ~(dune_version : Syntax.Version.t) confs = let sexps = From 044c78281d850bd7f654923da8ca10f7244cb276 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 15:05:15 +0700 Subject: [PATCH 16/19] Use parsing context when parsing name, version, raw triple of sub systems Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 089b108e..ad7fbf9a 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -4,7 +4,7 @@ let parse_sub_systems ~parsing_context sexps = List.filter_map sexps ~f:(fun sexp -> let name, ver, data = Sexp.Of_sexp.(parse (triple string (located Syntax.Version.t) raw) - Univ_map.empty) sexp + parsing_context) sexp in match Sub_system_name.get name with | None -> From 04ee6b0b2d683a202fc79fa1d3b2dddcf5d389d4 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 2 Jul 2018 16:33:12 +0700 Subject: [PATCH 17/19] Set M.syntax when reading subsystems generated by dune Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index ad7fbf9a..5e1c0476 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -21,6 +21,17 @@ let parse_sub_systems ~parsing_context sexps = |> Sub_system_name.Map.mapi ~f:(fun name (_, version, data) -> let (module M) = Jbuild.Sub_system_info.get name in Syntax.check_supported M.syntax version; + let parsing_context = + (* We set the syntax to the version used when generating this subsystem. + We cannot do this for jbuild defined subsystems however since those use + 1.0 as the version. Which would correspond to the dune syntax (because + subsystems share the syntax of the dune lang) *) + match Univ_map.find_exn parsing_context (Syntax.key Stanza.syntax) with + | (0, 0) -> + parsing_context + | (_, _) -> + Univ_map.add parsing_context (Syntax.key M.syntax) (snd version) + in M.T (Sexp.Of_sexp.parse M.parse parsing_context data)) let of_sexp = From 6589464f216af43bb64f844ee76a944e93d92fcd Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Tue, 3 Jul 2018 09:22:57 +0100 Subject: [PATCH 18/19] Rewrite lexing of installed dune files Signed-off-by: Jeremie Dimino --- src/installed_dune_file.ml | 68 ++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 5e1c0476..0102555e 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -38,52 +38,50 @@ let of_sexp = let open Sexp.Of_sexp in let version = plain_string (fun ~loc -> function - | "1" | "2" -> () + | "1" -> (0, 0) + | "2" -> (1, 0) | v -> of_sexp_errorf loc "Unsupported version %S, only version 1 is supported" v) in sum [ "dune", - (version >>= fun () -> - get_all >>= fun parsing_context -> - list raw >>| - parse_sub_systems ~parsing_context) + (version >>= fun version -> + set (Syntax.key Stanza.syntax) version + (get_all >>= fun parsing_context -> + list raw >>| + parse_sub_systems ~parsing_context)) ] let load fname = Io.with_lexbuf_from_file fname ~f:(fun lexbuf -> - let (tokens, version_loc, version) = - let rec loop = function - | [_; _; _] as a -> List.rev a - | acc -> - begin match (Sexp.Lexer.token lexbuf : Sexp.Lexer.Token.t) with - | Eof -> List.rev acc - | t -> loop (t :: acc) - end - in - let loc = Sexp.Loc.of_lexbuf lexbuf in - match loop [] with - | [Lparen; Atom (A "dune"); Atom s] as tokens -> - (tokens, loc, Sexp.Atom.to_string s) - | _ -> Loc.fail loc "Unable to read (dune x.y ..) line file" + (* Installed dune files are versioned but they don't use the + [(lang ...)] line which was introduced after. Installed dune + files in version 1 are using the jbuild syntax and version 2 + are using the dune syntax, so we start by lexing the first + tokens with the dune lexer until we reach the file version, at + which point we can decide what lexer to use for the reset of + the file. *) + let state = ref 0 in + let lexer = ref Sexp.Lexer.token in + let lexer lb = + let token : Sexp.Lexer.Token.t = !lexer lb in + (match !state, token with + | 0, Lparen -> state := 1 + | 1, Atom (A "dune") -> state := 2 + | 2, Atom (A "1") -> state := 3; lexer := Sexp.Lexer.jbuild_token + | 2, Atom (A "2") -> state := 3; lexer := Sexp.Lexer.token + | 2, Atom (A version) -> + Loc.fail (Sexp.Loc.of_lexbuf lexbuf) "Unsupported version %S" version + | 3, _ -> () + | _ -> + Loc.fail (Sexp.Loc.of_lexbuf lexbuf) + "This .dune file looks invalid, it should \ + contain a S-expression of the form (dune x.y ..)" + ); + token in - let (lexer, syntax) = - match version with - | "1" -> (Sexp.Lexer.jbuild_token, (0, 0)) - | "2" -> (Sexp.Lexer.token, (1, 0)) - | _ -> Loc.fail version_loc "unknown version %S" version - in - (* push back the tokens that we already read *) - let lexer = - let pending_tokens = ref tokens in - fun lb -> - match !pending_tokens with - | [] -> lexer lb - | x :: xs -> pending_tokens := xs; x - in - Sexp.Of_sexp.parse of_sexp - (Univ_map.singleton (Syntax.key Stanza.syntax) syntax) + Sexp.Of_sexp.parse of_sexp Univ_map.empty (Sexp.Parser.parse ~lexer ~mode:Single lexbuf)) let gen ~(dune_version : Syntax.Version.t) confs = From e09695e116c35770c50917a7bc92f9c183e4ecea Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Tue, 3 Jul 2018 16:36:11 +0700 Subject: [PATCH 19/19] Relax versions for subsystems Signed-off-by: Rudi Grinberg --- src/installed_dune_file.ml | 4 ++-- src/stanza.ml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/installed_dune_file.ml b/src/installed_dune_file.ml index 0102555e..c8bfae70 100644 --- a/src/installed_dune_file.ml +++ b/src/installed_dune_file.ml @@ -99,8 +99,8 @@ let gen ~(dune_version : Syntax.Version.t) confs = ; Sexp.unsafe_atom_of_string (match dune_version with | (0, 0) -> "1" - | (1, 0) -> "2" - | _ -> + | (x, _) when x >= 1 -> "2" + | (_, _) -> Exn.code_error "Cannot generate dune with unknown version" ["dune_version", Syntax.Version.sexp_of_t dune_version]) ; List sexps diff --git a/src/stanza.ml b/src/stanza.ml index 898257f2..c7744586 100644 --- a/src/stanza.ml +++ b/src/stanza.ml @@ -16,7 +16,7 @@ module File_kind = struct type t = Sexp.syntax = Jbuild | Dune let of_syntax = function - | (0, 0) -> Jbuild + | (0, _) -> Jbuild | (_, _) -> Dune end