From abd931ee0b62551e8d825c910369ac6142ab63fe Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Wed, 27 Nov 2024 17:17:13 -0500 Subject: [PATCH] Add option `--avoid-dangling-refs` --- bin/main.ml | 4 +++- lib/generator.ml | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/bin/main.ml b/bin/main.ml index 2ab2160..ddb6973 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -46,12 +46,13 @@ let main = let doc = "Generate an ATD file from a list of JSON Schema / OpenAPI document" in let state_term = Term.( - const (fun skip_doc pad toplevel_types -> + const (fun skip_doc pad toplevel_types avoid_dangling_refs -> Generator. { with_doc = not skip_doc; protect_against_duplicates = (if pad then Some (ref []) else None); toplevel_types; + avoid_dangling_refs; } ) $ Arg.(value (flag (info [ "skip-doc" ] ~doc:"Skip documentation annotations."))) @@ -64,6 +65,7 @@ let main = value (opt_all string [] (info [ "only-matching" ] ~docv:"REGEXP" ~doc:"Only output types matching REGEXP.")) ) ) + $ Arg.(value (flag (info [ "avoid-dangling-refs" ] ~doc:"Convert dangling refs to json."))) ) in let paths = Arg.(non_empty & pos_all file [] & info [] ~docv:"FILES" ~doc) in diff --git a/lib/generator.ml b/lib/generator.ml index b7d1be1..03f9b4f 100644 --- a/lib/generator.ml +++ b/lib/generator.ml @@ -6,9 +6,11 @@ type state = { with_doc : bool; protect_against_duplicates : string list ref option; toplevel_types : [ `All | `Only of string list ]; + avoid_dangling_refs : bool; } -let default_state = { with_doc = true; protect_against_duplicates = None; toplevel_types = `All } +let default_state = + { with_doc = true; protect_against_duplicates = None; toplevel_types = `All; avoid_dangling_refs = false } let record_field_name _state str = let cleaned_field_name = Utils.sanitize_name str in @@ -232,7 +234,14 @@ and make_type_from_schema_or_ref state ~ancestors (schema_or_ref : schema or_ref match schema_or_ref, ancestors with | Obj schema, ([] | [ _ ]) -> process_schema_type state ~ancestors schema | Obj schema, ancestors -> process_nested_schema_type state ~ancestors schema - | Ref ref_, _ -> type_name (get_ref_name ref_) + | Ref ref_, _ -> begin + match + (not state.avoid_dangling_refs) + || List.exists (fun (name, _schema) -> String.equal (get_ref_name ref_) name) !input_toplevel_schemas + with + | true -> type_name (get_ref_name ref_) + | false -> Printf.sprintf "json (* %s *)" (String.concat "/" (List.rev ancestors)) + end and process_one_of state ~ancestors (schemas_or_refs : schema or_ref list) = let determine_variant_name = function