This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name fooppx)
|
||||
(modes byte)
|
||||
(kind ppx_rewriter)
|
||||
(libraries ppxlib))
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
let () =
|
||||
Ppxlib.Driver.register_transformation
|
||||
"linter"
|
||||
~impl:(fun s -> Format.eprintf "running rewriter@.%!"; s)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.12)
|
||||
> EOF
|
||||
|
||||
$ mkdir bin
|
||||
$ cat > bin/dune << EOF
|
||||
> (executable
|
||||
> (name e)
|
||||
> (preprocess (pps fooppx)))
|
||||
> EOF
|
||||
$ cat >bin/e.ml <<EOF
|
||||
> print_endline "Hello World"
|
||||
> EOF
|
||||
|
||||
$ dune exec -- bin/e.exe
|
||||
Hello World
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
(cram
|
||||
(applies_to ppx-rewriter 9650-bytecode-rewriter)
|
||||
(deps
|
||||
(package ppxlib)
|
||||
%{bin:ocamlfind}))
|
||||
|
||||
(cram
|
||||
(applies_to ppx-rewriter)
|
||||
(deps %{bin:ocamlfind}))
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
; Too many drivers
|
||||
(library
|
||||
(name foo2)
|
||||
(public_name foo.2)
|
||||
(modules foo2)
|
||||
(preprocess (pps ppx1 ppx2)))
|
||||
|
||||
; Incompatible with Dune
|
||||
(library
|
||||
(name foo3)
|
||||
(public_name foo.3)
|
||||
(modules foo3)
|
||||
(preprocess (pps ppx_other)))
|
||||
|
||||
; Incompatible cookies
|
||||
(library
|
||||
(name foo4)
|
||||
(public_name foo.4)
|
||||
(modules foo4)
|
||||
(preprocess (pps ppx3 ppx4)))
|
||||
|
||||
(rule (with-stdout-to foo1.ml (echo "")))
|
||||
(rule (with-stdout-to foo2.ml (echo "")))
|
||||
(rule (with-stdout-to foo3.ml (echo "")))
|
||||
(rule (with-stdout-to foo4.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name ppx1)
|
||||
(public_name foo.ppx1)
|
||||
(kind ppx_rewriter)
|
||||
(modules ())
|
||||
(libraries driver1))
|
||||
|
||||
(library
|
||||
(name ppx2)
|
||||
(public_name foo.ppx2)
|
||||
(kind ppx_rewriter)
|
||||
(modules ())
|
||||
(libraries driver2))
|
||||
|
||||
(library
|
||||
(name ppx3)
|
||||
(public_name foo.ppx3)
|
||||
(kind (ppx_rewriter (cookies (germany "spritzgeback"))))
|
||||
(modules ())
|
||||
(libraries driver2))
|
||||
|
||||
(library
|
||||
(name ppx4)
|
||||
(public_name foo.ppx4)
|
||||
(kind (ppx_rewriter (cookies (germany "lebkuchen") (library-name "%{library-name}"))))
|
||||
(modules ())
|
||||
(libraries driver2))
|
||||
|
||||
(library
|
||||
(name driver1)
|
||||
(public_name foo.driver1)
|
||||
(modules ())
|
||||
(ppx.driver (main "(fun () -> assert false)")))
|
||||
|
||||
(library
|
||||
(name driver2)
|
||||
(public_name foo.driver2)
|
||||
(modules ())
|
||||
(ppx.driver (main "(fun () -> assert false)")))
|
||||
|
||||
(library
|
||||
(name ppx_other)
|
||||
(public_name foo.ppx-other)
|
||||
(modules ())
|
||||
(kind ppx_rewriter))
|
||||
|
||||
(library
|
||||
(name driver_print_args)
|
||||
(modules ())
|
||||
(ppx.driver (main "(fun () -> Array.iter print_endline Sys.argv)")))
|
||||
|
||||
(rule (with-stdout-to test_ppx_args.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name ppx_with_cookies_print_args)
|
||||
(kind (ppx_rewriter
|
||||
(cookies (italy "%{env:ITALY=undefined}")
|
||||
(france "%{env:FRANCE=undefined}"))))
|
||||
(modules ())
|
||||
(libraries driver_print_args))
|
||||
|
||||
(env
|
||||
(_
|
||||
(env-vars
|
||||
(ITALY "Biscotti")
|
||||
(FRANCE "Petit Beurre")
|
||||
(AMERICA "Oreo")
|
||||
(ENGLAND "Snickerdoodle"))))
|
||||
|
||||
(library
|
||||
(name test_ppx_args)
|
||||
(modules test_ppx_args)
|
||||
(preprocess
|
||||
(pps -arg1 driver_print_args ppx_with_cookies_print_args -arg2 -arg3=%{env:AMERICA=undefined} --
|
||||
-foo bar %{env:ENGLAND=undefined})))
|
||||
|
||||
(library
|
||||
(name driver_print_tool)
|
||||
(public_name foo.driver_print_tool)
|
||||
(kind ppx_rewriter)
|
||||
(modules ())
|
||||
(libraries compiler-libs.common)
|
||||
(ppx.driver (main "\| (fun () ->
|
||||
"\| Ast_mapper.run_main (fun argv ->
|
||||
"\| Printf.eprintf "tool name: %s\nargs:%s\n"
|
||||
"\| (Ast_mapper.tool_name ())
|
||||
"\| (String.concat " " argv);
|
||||
"\| Ast_mapper.default_mapper))
|
||||
)))
|
||||
|
||||
(library
|
||||
(name ppx_with_cookies_print_tool)
|
||||
(kind (ppx_rewriter
|
||||
(cookies (italy "%{env:ITALY=undefined}")
|
||||
(france "%{env:FRANCE=undefined}"))))
|
||||
(modules ())
|
||||
(libraries driver_print_tool))
|
||||
|
||||
(rule (with-stdout-to test_ppx_staged.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name test_ppx_staged)
|
||||
(modules test_ppx_staged)
|
||||
(preprocess
|
||||
(staged_pps -arg1 driver_print_tool ppx_with_cookies_print_tool -arg2 -arg3=%{env:AMERICA=undefined} --
|
||||
-foo bar %{env:ENGLAND=undefined})))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.10)
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
Too many drivers
|
||||
|
||||
$ dune build foo2.cma
|
||||
File "dune", line 6, characters 13-28:
|
||||
6 | (preprocess (pps ppx1 ppx2)))
|
||||
^^^^^^^^^^^^^^^
|
||||
Error: Too many incompatible ppx drivers were found: foo.driver1 and
|
||||
foo.driver2.
|
||||
[1]
|
||||
|
||||
Not compatible with Dune
|
||||
|
||||
$ dune build foo3.cma
|
||||
File "dune", line 13, characters 13-28:
|
||||
13 | (preprocess (pps ppx_other)))
|
||||
^^^^^^^^^^^^^^^
|
||||
Error: No ppx driver were found. It seems that ppx_other is not compatible
|
||||
with Dune. Examples of ppx rewriters that are compatible with Dune are ones
|
||||
using ocaml-migrate-parsetree, ppxlib or ppx_driver.
|
||||
[1]
|
||||
|
||||
Incompatible Cookies
|
||||
|
||||
$ dune build foo4.cma
|
||||
File "dune", line 20, characters 13-28:
|
||||
20 | (preprocess (pps ppx3 ppx4)))
|
||||
^^^^^^^^^^^^^^^
|
||||
Error: foo.ppx3 and foo.ppx4 have inconsistent requests for cookie "germany";
|
||||
foo.ppx3 requests "spritzgeback" and foo.ppx4 requests "lebkuchen"
|
||||
[1]
|
||||
|
||||
Same, but with error pointing to .ppx
|
||||
|
||||
$ dune build .ppx/foo.ppx1+foo.ppx2/ppx.exe
|
||||
Error: invalid ppx key for _build/default/.ppx/foo.ppx1+foo.ppx2/ppx.exe
|
||||
[1]
|
||||
|
||||
$ dune build .ppx/foo.ppx-other/ppx.exe
|
||||
Error: invalid ppx key for _build/default/.ppx/foo.ppx-other/ppx.exe
|
||||
[1]
|
||||
|
||||
Test the argument syntax
|
||||
|
||||
$ dune build test_ppx_args.cma
|
||||
.ppx/7e2e4f08e99331b1c723b81d3aa870ba/ppx.exe
|
||||
-arg1
|
||||
-arg2
|
||||
-arg3=Oreo
|
||||
-foo
|
||||
bar
|
||||
Snickerdoodle
|
||||
--cookie
|
||||
france="Petit Beurre"
|
||||
--cookie
|
||||
italy="Biscotti"
|
||||
--cookie
|
||||
library-name="test_ppx_args"
|
||||
-o
|
||||
test_ppx_args.pp.ml
|
||||
--impl
|
||||
test_ppx_args.ml
|
||||
--as-ppx
|
||||
File "dune", lines 100-101, characters 2-136:
|
||||
100 | (pps -arg1 driver_print_args ppx_with_cookies_print_args -arg2 -arg3=%{env:AMERICA=undefined} --
|
||||
101 | -foo bar %{env:ENGLAND=undefined})))
|
||||
Error: Rule failed to generate the following targets:
|
||||
- test_ppx_args.pp.ml
|
||||
[1]
|
||||
|
||||
Test that going through the -ppx option of the compiler works
|
||||
|
||||
$ dune build test_ppx_staged.cma
|
||||
tool name: ocamlc
|
||||
args:--as-ppx -arg1 -arg2 -arg3=Oreo -foo bar Snickerdoodle --cookie france="Petit Beurre" --cookie italy="Biscotti" --cookie library-name="test_ppx_staged"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(library
|
||||
(public_name replacesdriver)
|
||||
(libraries compiler-libs.common)
|
||||
(modules ())
|
||||
(ppx.driver
|
||||
(main "(fun () -> print_endline \"replacesdriver\"; Array.iter print_endline Sys.argv)")
|
||||
(replaces testdriver)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.1)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(library
|
||||
(public_name testdriver)
|
||||
(libraries compiler-libs.common)
|
||||
(ppx.driver (main "(fun () -> Array.iter print_endline Sys.argv)")))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.6)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(rule (with-stdout-to driveruser.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name driveruser)
|
||||
(preprocess (pps -arg1 replacesdriver -arg2 -- -foo bar)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.6)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
(rule (with-stdout-to driveruser.ml (echo "")))
|
||||
|
||||
(library
|
||||
(public_name replacesdriver)
|
||||
(libraries compiler-libs.common)
|
||||
(modules ())
|
||||
(ppx.driver
|
||||
(main "(fun () -> print_endline \"replacesdriver\"; Array.iter print_endline Sys.argv)")
|
||||
(replaces testdriver)))
|
||||
|
||||
(library
|
||||
(name driveruser)
|
||||
(preprocess (pps -arg1 replacesdriver -arg2 -- -foo bar)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.9)
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
Test using installed drivers
|
||||
|
||||
$ dune build --root driver @install
|
||||
Entering directory 'driver'
|
||||
Leaving directory 'driver'
|
||||
$ OCAMLPATH=driver/_build/install/default/lib dune build --root use-external-driver driveruser.cma
|
||||
Entering directory 'use-external-driver'
|
||||
.ppx/d1c2c0cf2b61b462226db18f72732070/ppx.exe
|
||||
-arg1
|
||||
-arg2
|
||||
-foo
|
||||
bar
|
||||
--cookie
|
||||
library-name="driveruser"
|
||||
-o
|
||||
driveruser.pp.ml
|
||||
--impl
|
||||
driveruser.ml
|
||||
--as-ppx
|
||||
File "dune", line 6, characters 13-53:
|
||||
6 | (preprocess (pps -arg1 testdriver -arg2 -- -foo bar)))
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: Rule failed to generate the following targets:
|
||||
- driveruser.pp.ml
|
||||
Leaving directory 'use-external-driver'
|
||||
[1]
|
||||
|
||||
$ OCAMLPATH=driver/_build/install/default/lib dune build --root replaces driveruser.cma
|
||||
Entering directory 'replaces'
|
||||
replacesdriver
|
||||
.ppx/5c2c5102d9f019e3d5eee93d6abe2029/ppx.exe
|
||||
-arg1
|
||||
-arg2
|
||||
-foo
|
||||
bar
|
||||
--cookie
|
||||
library-name="driveruser"
|
||||
-o
|
||||
driveruser.pp.ml
|
||||
--impl
|
||||
driveruser.ml
|
||||
--as-ppx
|
||||
File "dune", line 13, characters 13-57:
|
||||
13 | (preprocess (pps -arg1 replacesdriver -arg2 -- -foo bar)))
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: Rule failed to generate the following targets:
|
||||
- driveruser.pp.ml
|
||||
Leaving directory 'replaces'
|
||||
[1]
|
||||
|
||||
$ OCAMLPATH=driver/_build/install/default/lib dune build --root driver-replaces @install
|
||||
Entering directory 'driver-replaces'
|
||||
Leaving directory 'driver-replaces'
|
||||
$ OCAMLPATH=driver/_build/install/default/lib:driver-replaces/_build/install/default/lib dune build --root replaces-external driveruser.cma
|
||||
Entering directory 'replaces-external'
|
||||
replacesdriver
|
||||
.ppx/5c2c5102d9f019e3d5eee93d6abe2029/ppx.exe
|
||||
-arg1
|
||||
-arg2
|
||||
-foo
|
||||
bar
|
||||
--cookie
|
||||
library-name="driveruser"
|
||||
-o
|
||||
driveruser.pp.ml
|
||||
--impl
|
||||
driveruser.ml
|
||||
--as-ppx
|
||||
File "dune", line 5, characters 13-57:
|
||||
5 | (preprocess (pps -arg1 replacesdriver -arg2 -- -foo bar)))
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: Rule failed to generate the following targets:
|
||||
- driveruser.pp.ml
|
||||
Leaving directory 'replaces-external'
|
||||
[1]
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(rule (with-stdout-to driveruser.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name driveruser)
|
||||
(modules driveruser)
|
||||
(preprocess (pps -arg1 testdriver -arg2 -- -foo bar)))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.1)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
(library
|
||||
(name driver_print_args)
|
||||
(kind ppx_rewriter)
|
||||
(modules ())
|
||||
(ppx.driver (main "(fun () -> Array.iter print_endline Sys.argv)")))
|
||||
|
||||
(rule (with-stdout-to test_ppx_args.ml (echo "")))
|
||||
|
||||
(library
|
||||
(name ppx_with_cookies_print_args)
|
||||
(kind (ppx_rewriter
|
||||
(cookies (italy "%{env:ITALY=undefined}")
|
||||
(france "%{env:FRANCE=undefined}"))))
|
||||
(modules ())
|
||||
(libraries driver_print_args))
|
||||
|
||||
(env (_ (env-vars (ITALY "Biscotti") (FRANCE "Petit Beurre") (AMERICA "Oreo") (ENGLAND "Snickerdoodle"))))
|
||||
|
||||
(library
|
||||
(name test_ppx_args)
|
||||
(modules test_ppx_args)
|
||||
(preprocess
|
||||
(pps -arg1 driver_print_args ppx_with_cookies_print_args -arg2 -arg3=%{env:AMERICA=undefined} --
|
||||
-foo bar %{env:ENGLAND=undefined} %{read-lines:ppx-args})))
|
||||
|
||||
(library
|
||||
(name driver_print_tool)
|
||||
(public_name foo.driver_print_tool)
|
||||
(kind ppx_rewriter)
|
||||
(modules ())
|
||||
(libraries compiler-libs.common)
|
||||
(ppx.driver (main "\| (fun () ->
|
||||
"\| Ast_mapper.run_main (fun argv ->
|
||||
"\| Printf.eprintf "tool name: %s\nargs:%s\n"
|
||||
"\| (Ast_mapper.tool_name ())
|
||||
"\| (String.concat " " argv);
|
||||
"\| Ast_mapper.default_mapper))
|
||||
)))
|
||||
|
||||
(library
|
||||
(name ppx_with_cookies_print_tool)
|
||||
(kind (ppx_rewriter
|
||||
(cookies (italy "%{env:ITALY=undefined}")
|
||||
(france "%{env:FRANCE=undefined}"))))
|
||||
(modules ())
|
||||
(libraries driver_print_tool))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 3.3)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
Args
|
||||
From
|
||||
A
|
||||
File
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Test the argument syntax with list expansion allowed (dune > 3.2)
|
||||
|
||||
$ dune build
|
||||
.ppx/7e2e4f08e99331b1c723b81d3aa870ba/ppx.exe
|
||||
-arg1
|
||||
-arg2
|
||||
-arg3=Oreo
|
||||
-foo
|
||||
bar
|
||||
Snickerdoodle
|
||||
Args
|
||||
From
|
||||
A
|
||||
File
|
||||
--cookie
|
||||
france="Petit Beurre"
|
||||
--cookie
|
||||
italy="Biscotti"
|
||||
--cookie
|
||||
library-name="test_ppx_args"
|
||||
-o
|
||||
test_ppx_args.pp.ml
|
||||
--impl
|
||||
test_ppx_args.ml
|
||||
--as-ppx
|
||||
File "dune", lines 23-24, characters 3-161:
|
||||
23 | (pps -arg1 driver_print_args ppx_with_cookies_print_args -arg2 -arg3=%{env:AMERICA=undefined} --
|
||||
24 | -foo bar %{env:ENGLAND=undefined} %{read-lines:ppx-args})))
|
||||
Error: Rule failed to generate the following targets:
|
||||
- test_ppx_args.pp.ml
|
||||
[1]
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
No ppx driver found
|
||||
|
||||
$ echo '(lang dune 2.8)' > dune-project
|
||||
$ cat >dune <<EOF
|
||||
> (library
|
||||
> (name foo1)
|
||||
> (public_name foo.1)
|
||||
> (modules foo1)
|
||||
> (preprocess (pps)))
|
||||
> EOF
|
||||
$ dune build
|
||||
File "dune", line 5, characters 13-18:
|
||||
5 | (preprocess (pps)))
|
||||
^^^^^
|
||||
Error: You must specify at least one ppx rewriter.
|
||||
[1]
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
Create ppx1 and exe:
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (library
|
||||
> (name ppx)
|
||||
> (kind ppx_rewriter)
|
||||
> (modules ppx)
|
||||
> (ppx.driver (main Ppx.main)))
|
||||
> (executable
|
||||
> (name the_exe)
|
||||
> (modules the_exe)
|
||||
> (preprocess (pps ppx --alert ++foo)))
|
||||
> EOF
|
||||
$ cat > ppx.ml <<EOF
|
||||
> let main () =
|
||||
> let out = ref "" in
|
||||
> let args =
|
||||
> [ ("-o", Arg.Set_string out, "")
|
||||
> ; ("--impl", Arg.Set_string (ref ""), "")
|
||||
> ; ("--as-ppx", Arg.Set (ref false), "")
|
||||
> ; ("--cookie", Arg.Set (ref false), "")
|
||||
> ; ("--alert", Arg.Set_string (ref ""), "")
|
||||
> ]
|
||||
> in
|
||||
> let anon _ = () in
|
||||
> Arg.parse (Arg.align args) anon "";
|
||||
> let out = open_out !out in
|
||||
> close_out out;
|
||||
> EOF
|
||||
$ touch the_exe.ml
|
||||
|
||||
$ dune build ./the_exe.exe
|
||||
File "dune", line 9, characters 30-35:
|
||||
9 | (preprocess (pps ppx --alert ++foo)))
|
||||
^^^^^
|
||||
Error: PPX args starting with `+' cannot be used before version 3.18 of the
|
||||
dune language
|
||||
Hint: Upgrade your dune-project to `(lang dune 3.18)'
|
||||
[1]
|
||||
|
||||
Works since Dune 3.18
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> EOF
|
||||
$ dune build ./the_exe.exe
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(executable
|
||||
(name w_omp_driver)
|
||||
(modules w_omp_driver)
|
||||
(preprocess
|
||||
(pps fooppx -- -flag -arg omp)))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(lang dune 1.7)
|
||||
(name fooppx)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name fooppx)
|
||||
(public_name fooppx)
|
||||
(kind ppx_rewriter)
|
||||
(libraries ppxlib))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
let flag = ref false
|
||||
let arg = ref ""
|
||||
|
||||
let () =
|
||||
Ppxlib.Driver.add_arg "-flag" (Arg.Set flag) ~doc:"";
|
||||
Ppxlib.Driver.add_arg "-arg" (Arg.Set_string arg) ~doc:"";
|
||||
Ppxlib.Driver.register_transformation
|
||||
"linter"
|
||||
~impl:(fun s ->
|
||||
if not !flag then (
|
||||
Format.eprintf "pass -flag to fooppx@.%!";
|
||||
exit 1
|
||||
);
|
||||
if !arg = "" then (
|
||||
Format.eprintf "pass -arg to fooppx@.%!"
|
||||
);
|
||||
Format.eprintf "-arg: %s@." !arg;
|
||||
s
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
$ dune build ./w_omp_driver.exe
|
||||
-arg: omp
|
||||
|
||||
This test is broken because ppx_driver doesn't support migrate custom arguments
|
||||
# $ dune build ./w_ppx_driver_flags.exe
|
||||
$ dune build && dune exec -- ocamlfind opt -package fooppx -ppxopt "fooppx,-flag" -linkpkg w_omp_driver.ml -o w_omp_driver.exe
|
||||
pass -arg to fooppx
|
||||
-arg:
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
open Ppxlib
|
||||
|
||||
let rules =
|
||||
let extension =
|
||||
Extension.declare "c" Expression Ast_pattern.__ (fun ~loc ~path:_ _ ->
|
||||
Ast_builder.Default.eint ~loc [%get_c])
|
||||
in
|
||||
[ Context_free.Rule.extension extension ]
|
||||
|
||||
let () = Ppxlib.Driver.register_transformation "rules" ~rules
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
open Ppxlib
|
||||
|
||||
let rules =
|
||||
let extension =
|
||||
Extension.declare "get_c" Expression Ast_pattern.__ (fun ~loc ~path:_ _ ->
|
||||
Ast_builder.Default.evar ~loc "C.c")
|
||||
in
|
||||
[ Context_free.Rule.extension extension ]
|
||||
|
||||
let () = Ppxlib.Driver.register_transformation "rules" ~rules
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
----------------------------------------------------------------------------------
|
||||
Handling ppx_runtime_libraries dependencies correctly
|
||||
|
||||
$ cat >sdune <<'EOF'
|
||||
> #!/usr/bin/env bash
|
||||
> DUNE_SANDBOX=symlink dune "$@"
|
||||
> EOF
|
||||
$ chmod +x sdune
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Incorrect cycle detection due to ppx_runtime_libraries (TODO: fix this bug!)
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 2.0)
|
||||
> (implicit_transitive_deps true)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (library
|
||||
> (name a)
|
||||
> (modules a)
|
||||
> (libraries b))
|
||||
> (library
|
||||
> (name b)
|
||||
> (kind ppx_rewriter)
|
||||
> (modules b ppx)
|
||||
> (libraries ppxlib)
|
||||
> (ppx_runtime_libraries c))
|
||||
> (library
|
||||
> (name c)
|
||||
> (modules c)
|
||||
> (libraries a))
|
||||
> EOF
|
||||
|
||||
$ mkdir -p bin
|
||||
$ cat >bin/dune <<EOF
|
||||
> (executable
|
||||
> (name main)
|
||||
> (preprocess (pps b))
|
||||
> (modules main))
|
||||
> EOF
|
||||
|
||||
$ cat >a.ml <<EOF
|
||||
> include B
|
||||
> let a = B.b - 1
|
||||
> EOF
|
||||
|
||||
$ cat >b.ml <<EOF
|
||||
> let b = 2
|
||||
> EOF
|
||||
|
||||
$ cat >c.ml <<EOF
|
||||
> include A
|
||||
> let c = A.a + 2
|
||||
> EOF
|
||||
|
||||
$ cat >bin/main.ml <<EOF
|
||||
> let () = Printf.printf "Should print 3: %d\n" [%get_c]
|
||||
> EOF
|
||||
|
||||
$ ./sdune exec bin/main.exe
|
||||
Error: Dependency cycle between:
|
||||
library "b" in _build/default
|
||||
-> library "a" in _build/default
|
||||
-> library "c" in _build/default
|
||||
-> library "b" in _build/default
|
||||
[1]
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Ppx rewriters (and their ppx_runtime_libraries information) are collected recursively
|
||||
In this case we have the following dependency graph:
|
||||
main --[pps]--> b ---> ppx --[runtime]--> c ---> a
|
||||
Note the direct dependency b ---> ppx that separates pps and runtime dependencies.
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (library
|
||||
> (name a)
|
||||
> (modules a))
|
||||
> (library
|
||||
> (name b)
|
||||
> (modules b)
|
||||
> (libraries ppx))
|
||||
> (library
|
||||
> (name ppx)
|
||||
> (modules ppx)
|
||||
> (kind ppx_rewriter)
|
||||
> (libraries ppxlib)
|
||||
> (ppx_runtime_libraries c))
|
||||
> (library
|
||||
> (name c)
|
||||
> (modules c)
|
||||
> (libraries a))
|
||||
> EOF
|
||||
|
||||
$ cat >a.ml <<EOF
|
||||
> let a = 2 - 1
|
||||
> EOF
|
||||
|
||||
$ ./sdune exec bin/main.exe
|
||||
Should print 3: 3
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Since Dune 2.2, it is not allowed to have a pps dependency on a library that has
|
||||
not been marked with (kind ppx_rewriter).
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 2.2)
|
||||
> (implicit_transitive_deps true)
|
||||
> EOF
|
||||
|
||||
$ ./sdune exec bin/main.exe
|
||||
File "bin/dune", line 3, characters 18-19:
|
||||
3 | (preprocess (pps b))
|
||||
^
|
||||
Error: Ppx dependency on a non-ppx library "b". If "b" is in fact a ppx
|
||||
rewriter library, it should have (kind ppx_rewriter) in its dune file.
|
||||
-> required by _build/default/bin/.main.eobjs/native/dune__exe__Main.cmx
|
||||
-> required by _build/default/bin/main.exe
|
||||
[1]
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Dependency cycle between ppx rewriters created via [ppx_runtime_libraries]
|
||||
In this case we have the following dependency graph:
|
||||
gen_c --[pps]--> ppx --[runtime]--> c --[pps]--> gen_c
|
||||
Note that pps dependencies are separated by a runtime dependency.
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (library
|
||||
> (name gen_c)
|
||||
> (modules gen_c)
|
||||
> (kind ppx_rewriter)
|
||||
> (libraries ppxlib)
|
||||
> (preprocess (pps ppx)))
|
||||
> (library
|
||||
> (name ppx)
|
||||
> (modules ppx)
|
||||
> (kind ppx_rewriter)
|
||||
> (libraries ppxlib)
|
||||
> (ppx_runtime_libraries c))
|
||||
> (library
|
||||
> (name c)
|
||||
> (modules c)
|
||||
> (libraries ppxlib)
|
||||
> (preprocess (pps gen_c)))
|
||||
> EOF
|
||||
|
||||
$ cat >c.ml <<EOF
|
||||
> let c = [%c]
|
||||
> EOF
|
||||
|
||||
$ cat >bin/dune <<EOF
|
||||
> (executable
|
||||
> (name main)
|
||||
> (libraries c)
|
||||
> (modules main))
|
||||
> EOF
|
||||
|
||||
$ cat >bin/main.ml <<EOF
|
||||
> let () = Printf.printf "Should be impossible: %d\n" C.c
|
||||
> EOF
|
||||
|
||||
$ ./sdune exec bin/main.exe
|
||||
Error: Dependency cycle between:
|
||||
library "c" in _build/default
|
||||
-> library "ppx" in _build/default
|
||||
-> library "gen_c" in _build/default
|
||||
-> library "c" in _build/default
|
||||
[1]
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
Create ppx1, ppx2 and exe:
|
||||
- ppx1 is a regular ppx rewriter
|
||||
- ppx2 is also a ppx rewriter, preprocessed with ppx1
|
||||
- exe depends on ppx2
|
||||
|
||||
$ mkdir -p project/ppx/ppx1 project/ppx/ppx2 project/exe
|
||||
$ cat > project/ppx/dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> (package (name the-ppx))
|
||||
> EOF
|
||||
$ cat > project/ppx/ppx1/dune <<EOF
|
||||
> (library
|
||||
> (name ppx1)
|
||||
> (public_name the-ppx.ppx1)
|
||||
> (kind ppx_rewriter)
|
||||
> (ppx.driver (main Ppx1.main)))
|
||||
> EOF
|
||||
$ cat > project/ppx/ppx1/ppx1.ml <<EOF
|
||||
> let main () =
|
||||
> let out = ref "" in
|
||||
> let args =
|
||||
> [ ("-o", Arg.Set_string out, "")
|
||||
> ; ("--impl", Arg.Set_string (ref ""), "")
|
||||
> ; ("--as-ppx", Arg.Set (ref false), "")
|
||||
> ; ("--cookie", Arg.Set (ref false), "")
|
||||
> ]
|
||||
> in
|
||||
> let anon _ = () in
|
||||
> Arg.parse (Arg.align args) anon "";
|
||||
> let out = open_out !out in
|
||||
> close_out out;
|
||||
> EOF
|
||||
$ cat > project/ppx/ppx2/dune <<EOF
|
||||
> (library
|
||||
> (name ppx2)
|
||||
> (public_name the-ppx.ppx2)
|
||||
> (preprocess (pps ppx1)) ; changing to the-ppx.ppx1 makes it work
|
||||
> (kind ppx_rewriter))
|
||||
> EOF
|
||||
$ cat > project/ppx/ppx2/ppx2.ml <<EOF
|
||||
> let main () = ()
|
||||
> EOF
|
||||
|
||||
$ cat > project/dune-project <<EOF
|
||||
> (lang dune 3.7)
|
||||
> (package (name the-exe))
|
||||
> EOF
|
||||
$ cat > project/exe/dune <<EOF
|
||||
> (executable
|
||||
> (name the_exe)
|
||||
> (public_name the-exe)
|
||||
> (libraries the-ppx.ppx2))
|
||||
> EOF
|
||||
$ touch project/exe/the_exe.ml
|
||||
|
||||
$ OCAMLPATH=$PWD/prefix/lib/:$OCAMLPATH dune build --root project ./exe/the_exe.exe
|
||||
Entering directory 'project'
|
||||
Leaving directory 'project'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(lang dune 1.7)
|
||||
(name a)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name a_kernel)
|
||||
(public_name a.kernel)
|
||||
(kind ppx_rewriter)
|
||||
(libraries ppxlib))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name a)
|
||||
(public_name a)
|
||||
(kind ppx_rewriter)
|
||||
(libraries a_kernel))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(library
|
||||
(name b)
|
||||
(public_name b)
|
||||
(preprocess
|
||||
(pps a)))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(lang dune 1.7)
|
||||
(name b)
|
||||
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.7)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
This test reproduces a scope resolution bug when resolving the preprocessor of a
|
||||
library.
|
||||
|
||||
$ dune build b/b.cma @install
|
||||
Loading…
Add table
Add a link
Reference in a new issue