-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add migrations for ppx.context's load_path
Signed-off-by: Nathan Rebours <[email protected]>
- Loading branch information
Showing
6 changed files
with
286 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
test/driver/ocaml-ppx-context-load-path-migration/driver.ml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
From_before_502.copy_structure before_502_ast | ||
|
||
let () = Ppxlib.Driver.V2.register_transformation ~impl "ocaml.ppx.context-test" | ||
let () = Ppxlib.Driver.standalone () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
; Remember to bump the enabled if to the latest supported OCaml | ||
|
||
(executable | ||
(name driver) | ||
(enabled_if | ||
(>= %{ocaml_version} "5.2")) | ||
(libraries ppxlib ppxlib.ast ppxlib.astlib ocaml-compiler-libs.common | ||
compiler-libs.common)) | ||
|
||
(cram | ||
(enabled_if | ||
(>= %{ocaml_version} "5.2")) | ||
(deps driver.exe)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
Note that this test shoud only be enabled with the latest supported OCaml | ||
version. | ||
|
||
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"]; | ||
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 = [] | ||
}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters