Merge pull request #1011 from rgrinberg/refactor-expander-osl

Refactor var expansion
This commit is contained in:
Rudi Grinberg 2018-07-13 16:56:18 +02:00 committed by GitHub
commit 3c639a9be7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 302 additions and 230 deletions

View File

@ -83,7 +83,7 @@ module Unexpanded : sig
: t
-> dir:Path.t
-> map_exe:(Path.t -> Path.t)
-> f:(String_with_vars.Var.t -> Syntax.Version.t -> Value.t list option)
-> f:(Value.t list option String_with_vars.expander)
-> Unresolved.t
end
@ -91,7 +91,7 @@ module Unexpanded : sig
: t
-> dir:Path.t
-> map_exe:(Path.t -> Path.t)
-> f:(String_with_vars.Var.t -> Syntax.Version.t -> Value.t list option)
-> f:(Value.t list option String_with_vars.expander)
-> Partial.t
end

View File

@ -10,6 +10,10 @@ module Ast = struct
| Union : ('a, 'b) t list -> ('a, 'b) t
| Diff : ('a, 'b) t * ('a, 'b) t -> ('a, 'b) t
| Include : String_with_vars.t -> ('a, unexpanded) t
let union = function
| [x] -> x
| xs -> Union xs
end
type 'ast generic =
@ -32,7 +36,7 @@ module Parse = struct
peek_exn >>= function
| Atom (loc, A "\\") -> Loc.fail loc "unexpected \\"
| (Atom (_, A "") | Quoted_string (_, _)) | Template _ ->
elt >>| fun x -> Element x
elt
| Atom (loc, A s) -> begin
match s with
| ":standard" ->
@ -43,7 +47,7 @@ module Parse = struct
| _ when s.[0] = ':' ->
Loc.fail loc "undefined symbol %s" s
| _ ->
elt >>| fun x -> Element x
elt
end
| List (_, Atom (loc, A s) :: _) -> begin
match s, kind with
@ -88,7 +92,8 @@ end
let t =
let open Stanza.Of_sexp in
get_all >>= fun context ->
located (Parse.without_include ~elt:(plain_string (fun ~loc s -> (loc, s))))
located (Parse.without_include
~elt:(plain_string (fun ~loc s -> Ast.Element (loc, s))))
>>| fun (loc, ast) ->
{ ast; loc = Some loc; context }
@ -210,10 +215,12 @@ let field ?(default=standard) name = Sexp.Of_sexp.field name t ~default
module Unexpanded = struct
type ast = (String_with_vars.t, Ast.unexpanded) Ast.t
type t = ast generic
let t =
let t : t Sexp.Of_sexp.t =
let open Stanza.Of_sexp in
get_all >>= fun context ->
located (Parse.with_include ~elt:String_with_vars.t)
located (
Parse.with_include
~elt:(String_with_vars.t >>| fun s -> Ast.Element s))
>>| fun (loc, ast) ->
{ ast
; loc = Some loc
@ -239,12 +246,11 @@ module Unexpanded = struct
let field ?(default=standard) name = Stanza.Of_sexp.field name t ~default
let files t ~f =
let rec loop acc (t : ast) =
let rec loop acc (ast : ast) =
let open Ast in
match t with
match ast with
| Element _ | Standard -> acc
| Include fn ->
String.Set.add acc (f fn)
| Include fn -> Path.Set.add acc (f fn)
| Union l ->
List.fold_left l ~init:acc ~f:loop
| Diff (l, r) ->
@ -255,7 +261,7 @@ module Unexpanded = struct
| Some (0, _)-> File_tree.Dune_file.Kind.Jbuild
| None | Some (_, _) -> Dune
in
(syntax, loop String.Set.empty t.ast)
(syntax, loop Path.Set.empty t.ast)
let has_special_forms t =
let rec loop (t : ast) =
@ -291,31 +297,41 @@ module Unexpanded = struct
in
loop t.ast Pos init
let expand t ~files_contents ~f =
let expand t ~dir ~files_contents ~(f : String_with_vars.t -> Value.t list) =
let context = t.context in
let f_elems s =
let loc = String_with_vars.loc s in
Ast.union
(List.map (f s) ~f:(fun s -> Ast.Element (loc, Value.to_string ~dir s)))
in
let rec expand (t : ast) : ast_expanded =
let open Ast in
match t with
| Element s -> Element (String_with_vars.loc s, f s)
| Element s -> f_elems s
| Standard -> Standard
| Include fn ->
let sexp =
let fn = f fn in
match String.Map.find files_contents fn with
let path =
match f fn with
| [x] -> Value.to_path ~dir x
| _ ->
Loc.fail (String_with_vars.loc fn)
"An unquoted templated expanded to more than one value. \
A file path is expected in this position."
in
match Path.Map.find files_contents path with
| Some x -> x
| None ->
Exn.code_error
"Ordered_set_lang.Unexpanded.expand"
[ "included-file", Quoted_string fn
; "files", Sexp.To_sexp.(list string)
(String.Map.keys files_contents)
[ "included-file", Path.sexp_of_t path
; "files", Sexp.To_sexp.(list Path.sexp_of_t)
(Path.Map.keys files_contents)
]
in
let open Stanza.Of_sexp in
parse
(Parse.without_include
~elt:(String_with_vars.t >>| fun s ->
(String_with_vars.loc s, f s)))
(Parse.without_include ~elt:(String_with_vars.t >>| f_elems))
context
sexp
| Union l -> Union (List.map l ~f:expand)

View File

@ -65,16 +65,17 @@ module Unexpanded : sig
(** List of files needed to expand this set *)
val files
: t
-> f:(String_with_vars.t -> string)
-> Sexp.syntax * String.Set.t
-> f:(String_with_vars.t -> Path.t)
-> Sexp.syntax * Path.Set.t
(** Expand [t] using with the given file contents. [file_contents] is a map from
filenames to their parsed contents. Every [(:include fn)] in [t] is replaced by
[Map.find files_contents fn]. Every element is converted to a string using [f]. *)
val expand
: t
-> files_contents:Sexp.Ast.t String.Map.t
-> f:(String_with_vars.t -> string)
-> dir:Path.t
-> files_contents:Sexp.Ast.t Path.Map.t
-> f:(String_with_vars.t -> Value.t list)
-> expanded
type position = Pos | Neg

View File

@ -187,7 +187,7 @@ module Map = struct
Syntax.Error.deleted_in (String_with_vars.Var.loc pform)
Stanza.syntax syntax_version ~what:(describe pform) ?repl
let expand t ~syntax_version ~pform =
let expand t pform syntax_version =
match String_with_vars.Var.payload pform with
| None ->
Option.map (expand t.vars ~syntax_version ~pform) ~f:(fun x ->

View File

@ -48,11 +48,7 @@ module Map : sig
val input_file : Path.t -> t
val expand
: t
-> syntax_version:Syntax.Version.t
-> pform:String_with_vars.Var.t
-> Expansion.t option
val expand : t -> Expansion.t option String_with_vars.expander
val empty : t
end

View File

@ -158,7 +158,7 @@ let concat_rev = function
| l -> String.concat (List.rev l) ~sep:""
module Mode = struct
type 'a t =
type _ t =
| Single : Value.t t
| Many : Value.t list t
@ -264,6 +264,8 @@ let partial_expand
end
| _ -> loop [] [] template.parts
type 'a expander = Var.t -> Syntax.Version.t -> 'a
let expand t ~mode ~dir ~f =
match
partial_expand t ~mode ~dir ~f:(fun var syntax_version ->

View File

@ -35,7 +35,7 @@ val is_var : t -> name:string -> bool
val text_only : t -> string option
module Mode : sig
type 'a t =
type _ t =
| Single : Value.t t
| Many : Value.t list t
end
@ -64,16 +64,18 @@ module Var : sig
val describe : t -> string
end
type 'a expander = Var.t -> Syntax.Version.t -> 'a
val expand
: t
-> mode:'a Mode.t
-> dir:Path.t
-> f:(Var.t -> Syntax.Version.t -> Value.t list option)
-> f:(Value.t list option expander)
-> 'a
val partial_expand
: t
-> mode:'a Mode.t
-> dir:Path.t
-> f:(Var.t -> Syntax.Version.t -> Value.t list option)
-> f:(Value.t list option expander)
-> 'a Partial.t

View File

@ -95,50 +95,49 @@ let expand_ocaml_config t pform name =
"Unknown ocaml configuration variable %S"
name
let (expand_vars_string, expand_vars_path) =
let expand t ~scope ~dir ?(bindings=Pform.Map.empty) s =
String_with_vars.expand ~mode:Single ~dir s ~f:(fun pform syntax_version ->
(match Pform.Map.expand bindings ~syntax_version ~pform with
| None -> Pform.Map.expand t.pforms ~syntax_version ~pform
| Some _ as x -> x)
|> Option.map ~f:(function
| Pform.Expansion.Var (Values l) -> l
| Macro (Ocaml_config, s) -> expand_ocaml_config t pform s
| Var Project_root -> [Value.Dir (Scope.root scope)]
| _ ->
Loc.fail (String_with_vars.Var.loc pform)
"%s isn't allowed in this position"
(String_with_vars.Var.describe pform)))
in
let expand_vars t ~scope ~dir ?bindings s =
expand t ~scope ~dir ?bindings s
|> Value.to_string ~dir
in
let expand_vars_path t ~scope ~dir ?bindings s =
expand t ~scope ~dir ?bindings s
|> Value.to_path ~error_loc:(String_with_vars.loc s) ~dir
in
(expand_vars, expand_vars_path)
let expand_vars t ~mode ~scope ~dir ?(bindings=Pform.Map.empty) s =
String_with_vars.expand ~mode ~dir s ~f:(fun pform syntax_version ->
(match Pform.Map.expand bindings pform syntax_version with
| None -> Pform.Map.expand t.pforms pform syntax_version
| Some _ as x -> x)
|> Option.map ~f:(function
| Pform.Expansion.Var (Values l) -> l
| Macro (Ocaml_config, s) -> expand_ocaml_config t pform s
| Var Project_root -> [Value.Dir (Scope.root scope)]
| _ ->
Loc.fail (String_with_vars.Var.loc pform)
"%s isn't allowed in this position"
(String_with_vars.Var.describe pform)))
let expand_vars_string t ~scope ~dir ?bindings s =
expand_vars t ~mode:Single ~scope ~dir ?bindings s
|> Value.to_string ~dir
let expand_vars_path t ~scope ~dir ?bindings s =
expand_vars t ~mode:Single ~scope ~dir ?bindings s
|> Value.to_path ~error_loc:(String_with_vars.loc s) ~dir
let expand_and_eval_set t ~scope ~dir ?bindings set ~standard =
let open Build.O in
let f = expand_vars_string t ~scope ~dir ?bindings in
let parse ~loc:_ s = s in
let (syntax, files) = Ordered_set_lang.Unexpanded.files set ~f in
match String.Set.to_list files with
let (syntax, files) =
let f = expand_vars_path t ~scope ~dir ?bindings in
Ordered_set_lang.Unexpanded.files set ~f in
let f = expand_vars t ~mode:Many ~scope ~dir ?bindings in
match Path.Set.to_list files with
| [] ->
let set =
Ordered_set_lang.Unexpanded.expand set ~files_contents:String.Map.empty ~f
Ordered_set_lang.Unexpanded.expand set ~dir
~files_contents:Path.Map.empty ~f
in
standard >>^ fun standard ->
Ordered_set_lang.String.eval set ~standard ~parse
| files ->
let paths = List.map files ~f:(Path.relative dir) in
| paths ->
Build.fanout standard (Build.all (List.map paths ~f:(fun f ->
Build.read_sexp f syntax)))
>>^ fun (standard, sexps) ->
let files_contents = List.combine files sexps |> String.Map.of_list_exn in
let set = Ordered_set_lang.Unexpanded.expand set ~files_contents ~f in
let files_contents = List.combine paths sexps |> Path.Map.of_list_exn in
let set = Ordered_set_lang.Unexpanded.expand set ~dir ~files_contents ~f in
Ordered_set_lang.String.eval set ~standard ~parse
module Env = struct
@ -560,39 +559,225 @@ module Scope_key = struct
sprintf "%s@%s" key (Dune_project.Name.encode scope)
end
type targets =
| Static of Path.t list
| Infer
| Alias
module Expander : sig
module Resolved_forms : sig
type t
(* Failed resolutions *)
val failures : t -> fail list
(* All "name" for %{lib:name:...}/%{lib-available:name} forms *)
val lib_deps : t -> Build.lib_deps
(* Static deps from %{...} variables. For instance %{exe:...} *)
val sdeps : t -> Path.Set.t
(* Dynamic deps from %{...} variables. For instance %{read:...} *)
val ddeps : t -> (unit, Value.t list) Build.t String.Map.t
end
type sctx = t
val with_expander
: sctx
-> dir:Path.t
-> dep_kind:Build.lib_dep_kind
-> scope:Scope.t
-> targets_written_by_user:targets
-> map_exe:(Path.t -> Path.t)
-> bindings:Pform.Map.t
-> f:(Value.t list option String_with_vars.expander -> 'a)
-> 'a * Resolved_forms.t
end = struct
module Resolved_forms = struct
type t =
{ (* Failed resolutions *)
mutable failures : fail list
; (* All "name" for %{lib:name:...}/%{lib-available:name} forms *)
mutable lib_deps : Build.lib_deps
; (* Static deps from %{...} variables. For instance %{exe:...} *)
mutable sdeps : Path.Set.t
; (* Dynamic deps from %{...} variables. For instance %{read:...} *)
mutable ddeps : (unit, Value.t list) Build.t String.Map.t
}
let failures t = t.failures
let lib_deps t = t.lib_deps
let sdeps t = t.sdeps
let ddeps t = t.ddeps
let empty () =
{ failures = []
; lib_deps = String.Map.empty
; sdeps = Path.Set.empty
; ddeps = String.Map.empty
}
let add_lib_dep acc lib kind =
acc.lib_deps <- String.Map.add acc.lib_deps lib kind
let add_fail acc fail =
acc.failures <- fail :: acc.failures;
None
let add_ddep acc ~key dep =
acc.ddeps <- String.Map.add acc.ddeps key dep;
None
end
type sctx = t
let path_exp path = [Value.Path path]
let str_exp str = [Value.String str]
let parse_lib_file ~loc s =
match String.lsplit2 s ~on:':' with
| None ->
Loc.fail loc "invalid %%{lib:...} form: %s" s
| Some x -> x
open Build.O
let expander ~acc sctx ~dir ~dep_kind ~scope ~targets_written_by_user
~map_exe ~bindings pform syntax_version =
let loc = String_with_vars.Var.loc pform in
let key = String_with_vars.Var.full_name pform in
let res =
Pform.Map.expand bindings pform syntax_version
|> Option.bind ~f:(function
| Pform.Expansion.Var (Values l) -> Some l
| Macro (Ocaml_config, s) -> Some (expand_ocaml_config sctx pform s)
| Var Project_root -> Some [Value.Dir (Scope.root scope)]
| Var (First_dep | Deps | Named_local) -> None
| Var Targets ->
begin match targets_written_by_user with
| Infer ->
Loc.fail loc "You cannot use %s with inferred rules."
(String_with_vars.Var.describe pform)
| Alias ->
Loc.fail loc "You cannot use %s in aliases."
(String_with_vars.Var.describe pform)
| Static l ->
Some (Value.L.dirs l) (* XXX hack to signal no dep *)
end
| Macro (Exe, s) -> Some (path_exp (map_exe (Path.relative dir s)))
| Macro (Dep, s) -> Some (path_exp (Path.relative dir s))
| Macro (Bin, s) -> begin
let sctx = host sctx in
match Artifacts.binary (artifacts sctx) s with
| Ok path -> Some (path_exp path)
| Error e ->
Resolved_forms.add_fail acc
({ fail = fun () -> Action.Prog.Not_found.raise e })
end
| Macro (Lib, s) -> begin
let lib_dep, file = parse_lib_file ~loc s in
Resolved_forms.add_lib_dep acc lib_dep dep_kind;
match
Artifacts.file_of_lib (artifacts sctx) ~loc ~lib:lib_dep ~file
with
| Ok path -> Some (path_exp path)
| Error fail -> Resolved_forms.add_fail acc fail
end
| Macro (Libexec, s) -> begin
let sctx = host sctx in
let lib_dep, file = parse_lib_file ~loc s in
Resolved_forms.add_lib_dep acc lib_dep dep_kind;
match
Artifacts.file_of_lib (artifacts sctx) ~loc ~lib:lib_dep ~file
with
| Error fail -> Resolved_forms.add_fail acc fail
| Ok path ->
if not Sys.win32 || Filename.extension s = ".exe" then begin
Some (path_exp path)
end else begin
let path_exe = Path.extend_basename path ~suffix:".exe" in
let dep =
Build.if_file_exists path_exe
~then_:(Build.path path_exe >>^ fun _ ->
path_exp path_exe)
~else_:(Build.path path >>^ fun _ ->
path_exp path)
in
Resolved_forms.add_ddep acc ~key dep
end
end
| Macro (Lib_available, s) -> begin
let lib = s in
Resolved_forms.add_lib_dep acc lib Optional;
Some (str_exp (string_of_bool (
Lib.DB.available (Scope.libs scope) lib)))
end
| Macro (Version, s) -> begin
match Package.Name.Map.find (Scope.project scope).packages
(Package.Name.of_string s) with
| Some p ->
let x =
Pkg_version.read sctx p >>^ function
| None -> [Value.String ""]
| Some s -> [String s]
in
Resolved_forms.add_ddep acc ~key x
| None ->
Resolved_forms.add_fail acc { fail = fun () ->
Loc.fail loc
"Package %S doesn't exist in the current project." s
}
end
| Macro (Read, s) -> begin
let path = Path.relative dir s in
let data =
Build.contents path
>>^ fun s -> [Value.String s]
in
Resolved_forms.add_ddep acc ~key data
end
| Macro (Read_lines, s) -> begin
let path = Path.relative dir s in
let data =
Build.lines_of path
>>^ Value.L.strings
in
Resolved_forms.add_ddep acc ~key data
end
| Macro (Read_strings, s) -> begin
let path = Path.relative dir s in
let data =
Build.strings path
>>^ Value.L.strings
in
Resolved_forms.add_ddep acc ~key data
end
| Macro (Path_no_dep, s) -> Some [Value.Dir (Path.relative dir s)])
in
Option.iter res ~f:(fun v ->
acc.sdeps <- Path.Set.union
(Path.Set.of_list (Value.L.deps_only v)) acc.sdeps
);
res
let with_expander sctx ~dir ~dep_kind ~scope ~targets_written_by_user
~map_exe ~bindings ~f =
let acc = Resolved_forms.empty () in
( f (expander ~acc sctx ~dir ~dep_kind ~scope ~targets_written_by_user ~map_exe ~bindings)
, acc
)
end
module Action = struct
open Build.O
module U = Action.Unexpanded
type targets =
type nonrec targets = targets =
| Static of Path.t list
| Infer
| Alias
type resolved_forms =
{ (* Failed resolutions *)
mutable failures : fail list
; (* All "name" for %{lib:name:...}/%{lib-available:name} forms *)
mutable lib_deps : Build.lib_deps
; (* Static deps from %{...} variables. For instance %{exe:...} *)
mutable sdeps : Path.Set.t
; (* Dynamic deps from %{...} variables. For instance %{read:...} *)
mutable ddeps : (unit, Value.t list) Build.t String.Map.t
}
let add_lib_dep acc lib kind =
acc.lib_deps <- String.Map.add acc.lib_deps lib kind
let add_fail acc fail =
acc.failures <- fail :: acc.failures;
None
let add_ddep acc ~key dep =
acc.ddeps <- String.Map.add acc.ddeps key dep;
None
let path_exp path = [Value.Path path]
let str_exp str = [Value.String str]
let map_exe sctx =
match sctx.host with
@ -604,140 +789,10 @@ module Action = struct
Path.append host.context.build_dir exe
| _ -> exe
let parse_lib_file ~loc s =
match String.lsplit2 s ~on:':' with
| None ->
Loc.fail loc "invalid %%{lib:...} form: %s" s
| Some x -> x
let expand_step1 sctx ~dir ~dep_kind ~scope ~targets_written_by_user
~map_exe ~bindings t =
let acc =
{ failures = []
; lib_deps = String.Map.empty
; sdeps = Path.Set.empty
; ddeps = String.Map.empty
}
in
let expand pform syntax_version =
let loc = String_with_vars.Var.loc pform in
let key = String_with_vars.Var.full_name pform in
let res =
Pform.Map.expand bindings ~syntax_version ~pform
|> Option.bind ~f:(function
| Pform.Expansion.Var (Values l) -> Some l
| Macro (Ocaml_config, s) -> Some (expand_ocaml_config sctx pform s)
| Var Project_root -> Some [Value.Dir (Scope.root scope)]
| Var (First_dep | Deps | Named_local) -> None
| Var Targets ->
begin match targets_written_by_user with
| Infer ->
Loc.fail loc "You cannot use %s with inferred rules."
(String_with_vars.Var.describe pform)
| Alias ->
Loc.fail loc "You cannot use %s in aliases."
(String_with_vars.Var.describe pform)
| Static l ->
Some (Value.L.dirs l) (* XXX hack to signal no dep *)
end
| Macro (Exe, s) -> Some (path_exp (map_exe (Path.relative dir s)))
| Macro (Dep, s) -> Some (path_exp (Path.relative dir s))
| Macro (Bin, s) -> begin
let sctx = host sctx in
match Artifacts.binary (artifacts sctx) s with
| Ok path -> Some (path_exp path)
| Error e ->
add_fail acc
({ fail = fun () -> Action.Prog.Not_found.raise e })
end
| Macro (Lib, s) -> begin
let lib_dep, file = parse_lib_file ~loc s in
add_lib_dep acc lib_dep dep_kind;
match
Artifacts.file_of_lib (artifacts sctx) ~loc ~lib:lib_dep ~file
with
| Ok path -> Some (path_exp path)
| Error fail -> add_fail acc fail
end
| Macro (Libexec, s) -> begin
let sctx = host sctx in
let lib_dep, file = parse_lib_file ~loc s in
add_lib_dep acc lib_dep dep_kind;
match
Artifacts.file_of_lib (artifacts sctx) ~loc ~lib:lib_dep ~file
with
| Error fail -> add_fail acc fail
| Ok path ->
if not Sys.win32 || Filename.extension s = ".exe" then begin
Some (path_exp path)
end else begin
let path_exe = Path.extend_basename path ~suffix:".exe" in
let dep =
Build.if_file_exists path_exe
~then_:(Build.path path_exe >>^ fun _ ->
path_exp path_exe)
~else_:(Build.path path >>^ fun _ ->
path_exp path)
in
add_ddep acc ~key dep
end
end
| Macro (Lib_available, s) -> begin
let lib = s in
add_lib_dep acc lib Optional;
Some (str_exp (string_of_bool (
Lib.DB.available (Scope.libs scope) lib)))
end
| Macro (Version, s) -> begin
match Package.Name.Map.find (Scope.project scope).packages
(Package.Name.of_string s) with
| Some p ->
let x =
Pkg_version.read sctx p >>^ function
| None -> [Value.String ""]
| Some s -> [String s]
in
add_ddep acc ~key x
| None ->
add_fail acc { fail = fun () ->
Loc.fail loc
"Package %S doesn't exist in the current project." s
}
end
| Macro (Read, s) -> begin
let path = Path.relative dir s in
let data =
Build.contents path
>>^ fun s -> [Value.String s]
in
add_ddep acc ~key data
end
| Macro (Read_lines, s) -> begin
let path = Path.relative dir s in
let data =
Build.lines_of path
>>^ Value.L.strings
in
add_ddep acc ~key data
end
| Macro (Read_strings, s) -> begin
let path = Path.relative dir s in
let data =
Build.strings path
>>^ Value.L.strings
in
add_ddep acc ~key data
end
| Macro (Path_no_dep, s) -> Some [Value.Dir (Path.relative dir s)])
in
Option.iter res ~f:(fun v ->
acc.sdeps <- Path.Set.union
(Path.Set.of_list (Value.L.deps_only v)) acc.sdeps
);
res
in
let t = U.partial_expand t ~dir ~map_exe ~f:expand in
(t, acc)
Expander.with_expander sctx ~dir ~dep_kind ~scope ~targets_written_by_user ~map_exe ~bindings
~f:(fun f -> U.partial_expand t ~dir ~map_exe ~f)
let expand_step2 ~dir ~dynamic_expansions ~bindings
~(deps_written_by_user : Path.t Jbuild.Bindings.t)
@ -748,7 +803,7 @@ module Action = struct
match String.Map.find dynamic_expansions key with
| Some _ as opt -> opt
| None ->
Option.map (Pform.Map.expand bindings ~syntax_version ~pform) ~f:(function
Option.map (Pform.Map.expand bindings pform syntax_version) ~f:(function
| Var Named_local ->
begin match Jbuild.Bindings.find deps_written_by_user key with
| None ->
@ -823,13 +878,13 @@ module Action = struct
sprintf "- %s" (Utils.describe_target target))
|> String.concat ~sep:"\n"));
let build =
Build.record_lib_deps_simple forms.lib_deps
Build.record_lib_deps_simple (Expander.Resolved_forms.lib_deps forms)
>>>
Build.path_set (Path.Set.union deps forms.sdeps)
Build.path_set (Path.Set.union deps (Expander.Resolved_forms.sdeps forms))
>>>
Build.arr (fun paths -> ((), paths))
>>>
let ddeps = String.Map.to_list forms.ddeps in
let ddeps = String.Map.to_list (Expander.Resolved_forms.ddeps forms) in
Build.first (Build.all (List.map ddeps ~f:snd))
>>^ (fun (vals, deps_written_by_user) ->
let dynamic_expansions =
@ -854,7 +909,7 @@ module Action = struct
>>>
Build.action_dyn () ~dir ~targets
in
match forms.failures with
match Expander.Resolved_forms.failures forms with
| [] -> build
| fail :: _ -> Build.fail fail >>> build
end