-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add json mapper for pp_ast #526
base: main
Are you sure you want to change the base?
Conversation
b73cfdd
to
a60d33c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a quick comment from me, I don't think we would want to add yojson as a dependency of ppxlib for this feature (I might be mistaken).
The implementation uses the lifter to lift values to JSON values (not actually print them, like pp_simple_val
does). So I wonder if this couldn't be its own little tool that depends on ppxlib?
One workaround if this were to be merged here would be to add yojson as a dependency for ppxlib-pp-ast and then ppxlib could just return the polymorphic variants that happen to correspond to the Yojson.Safe.t
variants?
Yes, as Patrick said, ppxlib should not depend on external libraries as it otherwise prevents them from being able to depend on ppxlib. The We could add a json lifter to ppxlib but given it's fairly easy to write one this could be done directly in Did you try to load the resulting JSON into AST explorer? It would be nice to have a working usecase for this before we merge this feature! |
@NathanReb Hey ya!
I've just pushed a PR on astexplorer refmt to add the ppxlib pp_ast working with this json feature: jchavarri/astexplorer-refmt#1 About the yojson, I'm working on removing it |
That's awesome! Let me know when this is ready for review! |
ccbaed9
to
03a46a1
Compare
Signed-off-by: pedrobslisboa <[email protected]>
03a46a1
to
01ffa5b
Compare
let pp_simple_val_to_json fmt simple_val = | ||
let rec aux indent fmt simple_val = | ||
match simple_val with | ||
| Unit -> Format.fprintf fmt {|"null"|} | ||
| Int i -> Format.fprintf fmt "%d" i | ||
| String s -> Format.fprintf fmt {|"%s"|} s | ||
| Special s -> Format.fprintf fmt {|"%s"|} s | ||
| Bool b -> Format.fprintf fmt "%b" b | ||
| Char c -> Format.fprintf fmt {|"%c"|} c | ||
| Float f -> Format.fprintf fmt "%f" f | ||
| Int32 i32 -> Format.fprintf fmt "%ld" i32 | ||
| Int64 i64 -> Format.fprintf fmt "%Ld" i64 | ||
| Nativeint ni -> Format.fprintf fmt "%nd" ni | ||
| Array l | Tuple l | List l -> | ||
Format.fprintf fmt "[\n"; | ||
List.iteri | ||
~f:(fun i sv -> | ||
if i > 0 then Format.fprintf fmt ",\n"; | ||
Format.fprintf fmt "%s" (String.make (indent + 2) ' '); | ||
aux (indent + 2) fmt sv) | ||
l; | ||
Format.fprintf fmt "\n%s]" (String.make indent ' ') | ||
| Record fields -> | ||
Format.fprintf fmt "{\n"; | ||
List.iteri | ||
~f:(fun i (k, v) -> | ||
if i > 0 then Format.fprintf fmt ",\n"; | ||
Format.fprintf fmt "%s\"%s\": " (String.make (indent + 2) ' ') k; | ||
aux (indent + 2) fmt v) | ||
fields; | ||
Format.fprintf fmt "\n%s}" (String.make indent ' ') | ||
| Constr (cname, []) -> Format.fprintf fmt {|"%s"|} cname | ||
| Constr (cname, [ (Constr (_, _ :: _) as x) ]) -> | ||
Format.fprintf fmt "{\n%s\"%s\": " (String.make (indent + 2) ' ') cname; | ||
aux (indent + 2) fmt x; | ||
Format.fprintf fmt "\n%s}" (String.make indent ' ') | ||
| Constr (cname, [ x ]) -> | ||
Format.fprintf fmt "{\n%s\"%s\": " (String.make (indent + 2) ' ') cname; | ||
aux (indent + 2) fmt x; | ||
Format.fprintf fmt "\n%s}" (String.make indent ' ') | ||
| Constr (cname, l) -> | ||
Format.fprintf fmt "{\n%s\"%s\": [\n" (String.make (indent + 2) ' ') cname; | ||
List.iteri | ||
~f:(fun i sv -> | ||
if i > 0 then Format.fprintf fmt ",\n"; | ||
Format.fprintf fmt "%s" (String.make (indent + 4) ' '); | ||
aux (indent + 4) fmt sv) | ||
l; | ||
Format.fprintf fmt "\n%s]\n%s}" (String.make (indent + 2) ' ') (String.make indent ' ') | ||
in | ||
aux 0 fmt simple_val |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@patricoferris @NathanReb I've just pushed this simple pretty-printing json function to remove the yojson.
One workaround if this were to be merged here would be to add yojson as a dependency for ppxlib-pp-ast and then ppxlib could return the polymorphic variants that happen to correspond to the Yojson.Safe.t variants?
I could let yojson as a ppxlib_pp_ast
dep and return the poly-vars to print jsons only at ppxlib_pp_ast
or on the usage of Ppxlib.pp_ast
, but it looked hacky as we would have the "pretty-printing" not printing the json but return those poly vars.
Another alternative would be ppxlib-tools
to have this dependency and pp_ast
to use it.
But as it was not hard to create a simple pp for json, I created it. It isn't as pretty as yojson cause we break every array/list/tuple/record line, but it does not feel like a problem right now.
BTW, I tried to follow pp_simple_val
way to print, but it had a strange indent structure, and I created this way. If any issue, just let me now.
@NathanReb BTW, I think now it's ready for review |
Description
Add
json
mapper onpp_ast
to improve usage in tools such as AST Explorer.The idea is to increment the @NathanReb PR #517
@NathanReb, your opinion on how to structure it better is very welcome.
@jchavarri @davesnx thank you for the help.
How
To use it, we just need to pass
--json
toppxlib-pp-ast.
It works with all other flags, such as--show-attrs
and--show-loc
.How to test
ppxlib-pp-ast test.ml
and check the resultppxlib-pp-ast --json test.ml
and check the result--json