@@ -54,40 +54,46 @@ let invalid_variable_error ~loc variable =
5454 [ Pp. textf " Variable %S is not supported." (OpamVariable. to_string variable) ]
5555;;
5656
57- let opam_variable_to_slang ~loc packages variable =
58- let variable_string = OpamVariable. to_string variable in
59- let convert_with_package_name package_name =
60- match is_valid_package_variable_name variable_string with
61- | false -> invalid_variable_error ~loc variable
62- | true ->
63- let pform =
64- let name = Package_variable_name. of_string variable_string in
65- let scope : Package_variable.Scope.t =
66- match package_name with
67- | None -> Self
68- | Some p -> Package (Package_name. of_opam_package_name p)
69- in
70- Package_variable. to_pform { Package_variable. name; scope }
71- in
72- Slang. pform pform
57+ let opam_variable_to_slang =
58+ let opam_var_to_pform variable_name scope =
59+ Package_variable. to_pform { Package_variable. name = variable_name; scope }
60+ |> Slang. pform
7361 in
74- match packages with
75- | [] ->
76- (match is_valid_global_variable_name variable_string with
77- | false ->
78- (* Note that there's no syntactic distinction between global variables
62+ fun ~loc ~packages_in_solution packages variable ->
63+ let variable_string = OpamVariable. to_string variable in
64+ let variable_name = Package_variable_name. of_string variable_string in
65+ let convert_with_package_name package_name =
66+ match is_valid_package_variable_name variable_string with
67+ | false -> invalid_variable_error ~loc variable
68+ | true ->
69+ (match package_name with
70+ | Some p ->
71+ let pkg_name = Package_name. of_opam_package_name p in
72+ let pform = opam_var_to_pform variable_name (Package pkg_name) in
73+ if Package_name.Map. mem packages_in_solution pkg_name
74+ then pform
75+ else
76+ Package_variable_name. absent_package_value variable_name
77+ |> Option. value ~default: pform
78+ | None -> opam_var_to_pform variable_name Self )
79+ in
80+ match packages with
81+ | [] ->
82+ (match is_valid_global_variable_name variable_string with
83+ | false ->
84+ (* Note that there's no syntactic distinction between global variables
7985 and package variables in the current package. This check will prevent
8086 invalid global variable names from being used for package variables in the
8187 current package where the optional qualifier "_:" is omitted. *)
82- invalid_variable_error ~loc variable
83- | true ->
84- (match Pform.Var. of_opam_global_variable_name variable_string with
85- | Some global_var -> Slang. pform (Pform. Var global_var)
86- | None -> convert_with_package_name None ))
87- | [ package_name ] -> convert_with_package_name package_name
88- | many ->
89- let many = List. map many ~f: convert_with_package_name in
90- Slang. blang (Blang. And (List. map many ~f: (fun slang -> Blang. Expr slang)))
88+ invalid_variable_error ~loc variable
89+ | true ->
90+ (match Pform.Var. of_opam_global_variable_name variable_string with
91+ | Some global_var -> Slang. pform (Pform. Var global_var)
92+ | None -> convert_with_package_name None ))
93+ | [ package_name ] -> convert_with_package_name package_name
94+ | many ->
95+ let many = List. map many ~f: convert_with_package_name in
96+ Slang. blang (Blang. And (List. map many ~f: (fun slang -> Blang. Expr slang)))
9197;;
9298
9399(* Handles the special case for packages whose names contain '+' characters
@@ -113,29 +119,33 @@ let desugar_special_string_interpolation_syntax
113119 | _ -> fident
114120;;
115121
116- let opam_fident_to_slang ~loc fident =
122+ let opam_fident_to_slang ~loc ~ packages_in_solution fident =
117123 let packages, variable, string_converter =
118124 OpamFilter. desugar_fident fident |> desugar_special_string_interpolation_syntax
119125 in
120- let slang = opam_variable_to_slang ~loc packages variable in
126+ let slang = opam_variable_to_slang ~loc ~packages_in_solution packages variable in
121127 match string_converter with
122128 | None -> slang
123129 | Some (then_ , else_ ) ->
124130 (* The "else" case is also used when evaluating the condition would expand
125131 an undefined variable. The catch_undefined_var operator is used to
126132 convert expressions that throw undefined variable exceptions into false.
127133 *)
128- let condition =
129- Blang. Expr (Slang. catch_undefined_var slang ~fallback: (Slang. bool false ))
130- in
131- Slang. if_ condition ~then_: (Slang. text then_) ~else_: (Slang. text else_)
134+ (match slang with
135+ | Form (_ , Blang (Blang. Const false )) -> Slang. text else_
136+ | _ ->
137+ let condition =
138+ Blang. Expr (Slang. catch_undefined_var slang ~fallback: (Slang. bool false ))
139+ in
140+ Slang. if_ condition ~then_: (Slang. text then_) ~else_: (Slang. text else_))
132141;;
133142
134- let opam_raw_fident_to_slang ~loc raw_ident =
135- OpamTypesBase. filter_ident_of_string raw_ident |> opam_fident_to_slang ~loc
143+ let opam_raw_fident_to_slang ~loc ~packages_in_solution raw_ident =
144+ OpamTypesBase. filter_ident_of_string raw_ident
145+ |> opam_fident_to_slang ~loc ~packages_in_solution
136146;;
137147
138- let opam_string_to_slang ~package ~loc opam_string =
148+ let opam_string_to_slang ~packages_in_solution ~ package ~loc opam_string =
139149 Re.Seq. split_full OpamFilter. string_interp_regex opam_string
140150 |> Seq. map ~f: (function
141151 | `Text text -> Slang. text text
@@ -146,7 +156,7 @@ let opam_string_to_slang ~package ~loc opam_string =
146156 when String. starts_with ~prefix: " %{" interp
147157 && String. ends_with ~suffix: " }%" interp ->
148158 let ident = String. sub ~pos: 2 ~len: (String. length interp - 4 ) interp in
149- opam_raw_fident_to_slang ~loc ident
159+ opam_raw_fident_to_slang ~loc ~packages_in_solution ident
150160 | other ->
151161 User_error. raise
152162 ~loc
@@ -216,11 +226,11 @@ let resolve_depopts ~resolve depopts =
216226 These two Slang operators are used to emulate Opam's undefined value
217227 semantics.
218228*)
219- let filter_to_blang ~package ~loc filter =
229+ let filter_to_blang ~packages_in_solution ~ package ~loc filter =
220230 let filter_to_slang (filter : OpamTypes.filter ) =
221231 match filter with
222- | FString s -> opam_string_to_slang ~package ~loc s
223- | FIdent fident -> opam_fident_to_slang ~loc fident
232+ | FString s -> opam_string_to_slang ~packages_in_solution ~ package ~loc s
233+ | FIdent fident -> opam_fident_to_slang ~loc ~packages_in_solution fident
224234 | other ->
225235 Code_error. raise
226236 " The opam file parser should only allow identifiers and strings in places where \
@@ -268,6 +278,7 @@ let filter_to_blang ~package ~loc filter =
268278;;
269279
270280let opam_commands_to_actions
281+ ~packages_in_solution
271282 get_solver_var
272283 loc
273284 package
@@ -287,8 +298,9 @@ let opam_commands_to_actions
287298 let slang =
288299 let slang =
289300 match simple_arg with
290- | CString s -> opam_string_to_slang ~package ~loc s
291- | CIdent ident -> opam_raw_fident_to_slang ~loc ident
301+ | CString s -> opam_string_to_slang ~packages_in_solution ~package ~loc s
302+ | CIdent ident ->
303+ opam_raw_fident_to_slang ~loc ~packages_in_solution ident
292304 in
293305 Slang. simplify slang
294306 in
@@ -298,8 +310,9 @@ let opam_commands_to_actions
298310 | None -> slang
299311 | Some filter ->
300312 let filter_blang =
301- filter_to_blang ~package ~loc filter |> Slang. simplify_blang
302- and slang = slang in
313+ filter_to_blang ~packages_in_solution ~package ~loc filter
314+ |> Slang. simplify_blang
315+ in
303316 let filter_blang_handling_undefined =
304317 (* Wrap the blang filter so that if any undefined
305318 variables are expanded while evaluating the filter,
@@ -318,17 +331,18 @@ let opam_commands_to_actions
318331 if List. is_empty terms
319332 then None
320333 else (
321- let action =
322- let action = Action. Run terms in
323- match filter with
324- | None -> action
325- | Some filter ->
326- let condition =
327- filter_to_blang ~package ~loc filter |> Slang. simplify_blang
328- in
329- Action. When (condition, action)
330- in
331- Some action))
334+ let action = Action. Run terms in
335+ match filter with
336+ | None -> Some action
337+ | Some filter ->
338+ let condition =
339+ filter_to_blang ~packages_in_solution ~package ~loc filter
340+ |> Slang. simplify_blang
341+ in
342+ (match condition with
343+ | Const true -> Some action
344+ | Const false -> None
345+ | _ -> Some (Action. When (condition, action)))))
332346;;
333347
334348(* Standard package variables that are always defined at build time.
@@ -379,12 +393,13 @@ let rec filter_vars_are_defined : OpamTypes.filter -> bool = function
379393
380394 Depexts with filters that reference undefined variables are excluded, as
381395 they would error at build time. *)
382- let depexts_to_conditional_external_dependencies package depexts =
396+ let depexts_to_conditional_external_dependencies ~ packages_in_solution package depexts =
383397 List. filter_map depexts ~f: (fun (sys_pkgs , filter ) ->
384398 let open Option.O in
385399 let * () = Option. some_if (filter_vars_are_defined filter) () in
386400 let condition =
387- filter_to_blang ~package ~loc: Loc. none filter |> Slang. simplify_blang
401+ filter_to_blang ~packages_in_solution ~package ~loc: Loc. none filter
402+ |> Slang. simplify_blang
388403 in
389404 let + () = Option. some_if (not (Slang.Blang. equal condition Slang.Blang. false_)) () in
390405 let external_package_names =
@@ -489,6 +504,7 @@ let opam_package_to_lock_file_pkg
489504 Solver_stats.Updater. expand_variable stats_updater variable_name;
490505 Solver_env. get solver_env variable_name
491506 in
507+ let packages_in_solution = version_by_package_name in
492508 let build_command =
493509 if Resolved_package. dune_build resolved_package
494510 then Some Lock_dir.Build_command. Dune
@@ -512,12 +528,17 @@ let opam_package_to_lock_file_pkg
512528 | None -> action
513529 | Some filter ->
514530 let blang =
515- filter_to_blang ~package: opam_package ~loc: Loc. none filter
531+ filter_to_blang
532+ ~packages_in_solution
533+ ~package: opam_package
534+ ~loc: Loc. none
535+ filter
516536 |> Slang. simplify_blang
517537 in
518538 Action. When (blang, action))
519539 and build_step =
520540 opam_commands_to_actions
541+ ~packages_in_solution
521542 get_solver_var
522543 loc
523544 opam_package
@@ -548,6 +569,7 @@ let opam_package_to_lock_file_pkg
548569 if portable_lock_dir
549570 then
550571 depexts_to_conditional_external_dependencies
572+ ~packages_in_solution
551573 opam_package
552574 (OpamFile.OPAM. depexts opam_file)
553575 else (
@@ -566,7 +588,7 @@ let opam_package_to_lock_file_pkg
566588 in
567589 let install_command =
568590 OpamFile.OPAM. install opam_file
569- |> opam_commands_to_actions get_solver_var loc opam_package
591+ |> opam_commands_to_actions ~packages_in_solution get_solver_var loc opam_package
570592 |> make_action
571593 |> Option. map ~f: (fun action -> lockfile_field_choice (build_env action))
572594 |> Option. value ~default: Lock_dir.Conditional_choice. empty
0 commit comments