This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,92 @@
module To_before_502 =
Ppxlib_ast.Convert (Ppxlib_ast.Js) (Ppxlib_ast__.Versions.OCaml_501)
module From_before_502 =
Ppxlib_ast.Convert (Ppxlib_ast__.Versions.OCaml_501) (Ppxlib_ast.Js)
module Before_502_to_ocaml =
Ppxlib_ast.Convert
(Ppxlib_ast__.Versions.OCaml_501)
(Ppxlib_ast.Compiler_version)
module OCaml_501 = Ppxlib_ast__.Versions.OCaml_501.Ast
let rec unfold_list_lit x next =
let open OCaml_501.Parsetree in
let open Astlib.Longident in
match next.pexp_desc with
| Pexp_construct ({ txt = Lident "[]"; _ }, None) -> [ x ]
| Pexp_construct
( { txt = Lident "::"; _ },
Some { pexp_desc = Pexp_tuple [ elm; rest ]; _ } ) ->
x :: unfold_list_lit elm rest
| _ -> invalid_arg "list_lit"
(* Only deals with the basic blocks needed for ocaml.ppx.context *)
let rec basic_expr_to_string expr =
let open OCaml_501.Parsetree in
let open Astlib.Longident in
match expr.pexp_desc with
| Pexp_constant (Pconst_string (s, _, None)) -> Printf.sprintf "%S" s
| Pexp_ident { txt = Lident name; _ } -> name
| Pexp_tuple l ->
let strs = List.map basic_expr_to_string l in
"(" ^ String.concat ", " strs ^ ")"
| Pexp_construct ({ txt = Lident s; _ }, None) -> s
| Pexp_construct
( { txt = Lident "::"; _ },
Some { pexp_desc = Pexp_tuple [ elm; rest ]; _ } ) ->
let exprs = unfold_list_lit elm rest in
let strs = List.map basic_expr_to_string exprs in
"[" ^ String.concat "; " strs ^ "]"
| _ -> invalid_arg "basic_expr_to_string"
let print_field (lident_loc, expr) =
match lident_loc with
| { OCaml_501.Asttypes.txt = Astlib.Longident.Lident name; _ } ->
Printf.printf " %s: %s;\n" name (basic_expr_to_string expr)
| _ -> ()
let print_ocaml_ppx_context stri =
let open OCaml_501.Parsetree in
match stri.pstr_desc with
| Pstr_attribute
{
attr_payload =
PStr
[
{
pstr_desc =
Pstr_eval ({ pexp_desc = Pexp_record (fields, None); _ }, _);
_;
};
];
_;
} ->
Printf.printf "[@@@ocaml.ppx.context\n";
Printf.printf " {\n";
List.iter print_field fields;
Printf.printf " }\n";
Printf.printf "]\n"
| _ -> ()
let is_ppx_context stri =
let open OCaml_501.Parsetree in
match stri.pstr_desc with
| Pstr_attribute
{ attr_name = { OCaml_501.Asttypes.txt = "ocaml.ppx.context"; _ }; _ } ->
true
| _ -> false
let impl _ctxt str =
let before_502_ast = To_before_502.copy_structure str in
let ppx_context = List.find is_ppx_context before_502_ast in
Printf.printf "ocaml.ppx.context before 5.02:\n";
print_ocaml_ppx_context ppx_context;
let round_trip = Before_502_to_ocaml.copy_structure_item ppx_context in
Printf.printf "ocaml.ppx.context round tripped:\n";
Ocaml_common.Pprintast.structure_item Format.std_formatter round_trip;
str
let () = Ppxlib.Driver.V2.register_transformation ~impl "ocaml.ppx.context-test"
let () = Ppxlib.Driver.standalone ()

View file

@ -0,0 +1,16 @@
(executable
(name driver)
(enabled_if
(>= %{ocaml_version} "5.2"))
(libraries
ppxlib
ppxlib.ast
ppxlib.astlib
ocaml-compiler-libs.common
compiler-libs.common))
(cram
(package ppxlib)
(enabled_if
(>= %{ocaml_version} "5.2"))
(deps driver.exe))

View file

@ -0,0 +1,73 @@
In 5.2 the format of ocaml.ppx.context load_path changed.
To ensure compat, we defined migration for ocaml.ppx.context attributes
We write such an attribute to an .ml file. The compiler will add its own
and it should be consumed by the driver but our handwritten attribute will
be migrated as well and should remain in the AST.
$ cat > test.ml << EOF
> let x = 1
> [@@@ocaml.ppx.context
> {
> tool_name = "ocaml";
> include_dirs = ["foo"];
> hidden_include_dirs = [];
> load_path = (["foo"; "bar"], ["baz"]);
> open_modules = [];
> for_package = None;
> debug = true;
> use_threads = false;
> use_vmthreads = false;
> recursive_types = false;
> principal = false;
> transparent_modules = false;
> unboxed_types = false;
> unsafe_string = false;
> cookies = []
> }]
> EOF
We then run a custom driver that will read our ast, migrate it back to 5.01,
pretty print the ocaml.ppx.context, convert it back to the latest version and
pretty print it again. This last, round-tripped version should be identical to
the one above.
$ ./driver.exe --impl test.ml -o ignore.ml
ocaml.ppx.context before 5.02:
[@@@ocaml.ppx.context
{
tool_name: "ocaml";
include_dirs: ["foo"];
hidden_include_dirs: [];
load_path: ["foo"; "bar"; "baz"];
open_modules: [];
for_package: None;
debug: true;
use_threads: false;
use_vmthreads: false;
recursive_types: false;
principal: false;
transparent_modules: false;
unboxed_types: false;
unsafe_string: false;
cookies: [];
}
]
ocaml.ppx.context round tripped:
[@@@ocaml.ppx.context
{
tool_name = "ocaml";
include_dirs = ["foo"];
hidden_include_dirs = [];
load_path = (["foo"; "bar"], ["baz"]);
open_modules = [];
for_package = None;
debug = true;
use_threads = false;
use_vmthreads = false;
recursive_types = false;
principal = false;
transparent_modules = false;
unboxed_types = false;
unsafe_string = false;
cookies = []
}]