@@ -2,102 +2,67 @@ open !StdLabels
22open ! MoreLabels
33open ! Utils
44
5+ type indent = [ `Begin | `End | `EndBegin | `None | `Raw ]
6+
57type t = {
6- mutable indent : string ;
7- mutable code : string list ;
8+ mutable indent : int ;
9+ mutable code : ( indent * string ) list ;
810}
911
10- let init () = {indent = " " ; code = [] }
11- let incr t = t.indent < - " " ^ t.indent
12+ let init () = {indent = 0 ; code = [] }
13+ let incr t = t.indent < - t.indent + 1
1214let decr t =
13- match String. length t.indent > = 2 with
14- | true ->
15- t.indent < - String. sub ~pos: 0 ~len: (String. length t.indent - 2 ) t.indent
16- | false -> failwith " Cannot decr indentation level at this point"
17-
18- (* * Merge groups when the list groups ends with a line that starts with a '-' *)
19- let rec merge_list_groups = function
20- | (false , l1 ) :: (true , l2 ) :: xs ->
21- begin match List. rev l1 with
22- | s :: _ when String. starts_with_regex ~regex: " [ ]*- " s ->
23- (false , l1 @ l2) :: merge_list_groups xs
24- | _ -> (false , l1) :: (true , l2) :: merge_list_groups xs
25- end
26- | x :: xs ->
27- x :: merge_list_groups xs
28- | [] -> []
29-
30- let remove_trailing_empty_lines lines =
31- lines
32- |> List. rev
33- |> List. drop_while ~f: ((= ) " " )
34- |> List. rev
35-
36- let escape_comment s =
37- String. to_seq s
38- |> Seq. map (function
39- | '{' | '}' | '[' | ']' | '@' | '\\' as ch -> Printf. sprintf " \\ %c" ch
40- | ch -> Printf. sprintf " %c" ch
41- )
42- |> List. of_seq
43- |> String. concat ~sep: " "
44-
45-
46- let map_comments comments =
47- comments
48- |> String. concat ~sep: " \n\n "
49- |> String. split_on_char ~sep: '\n'
50- |> List. map ~f: (String. trim_end ~chars: " \n\t " )
51- |> List. group ~f: (fun s -> String. starts_with ~prefix: " " s && not (String. starts_with_regex ~regex: " [ ]*- " s))
52- |> merge_list_groups
53- |> List. map ~f: (function
54- | (false , lines ) ->
55- lines
56- |> List. map ~f: String. trim
57- |> remove_trailing_empty_lines
58- |> List. map ~f: escape_comment
59- | (true , lines ) ->
60- let lines =
61- lines
62- |> List. map ~f: (String. replace ~substring: " v}" ~f: (fun _ -> " v\\ }" ))
63- |> remove_trailing_empty_lines
64- in
65- " {v" :: lines @ [" v}" ]
66- )
67- |> List. flatten
68- |> List. rev
69- |> List. drop_while ~f: (fun x -> x = " " )
70- |> List. rev
15+ match t.indent = 0 with
16+ | true -> failwith " Cannot decr indentation level at this point"
17+ | false -> t.indent < - t.indent - 1
7118
7219let emit t indent fmt =
73- let prepend s =
74- String. split_on_char ~sep: '\n' s
75- |> List. iter ~f: (fun line ->
76- (* Replace tabs with indent *)
77- let line =
78- " " :: String. split_on_char ~sep: '\t' line
79- |> String. concat ~sep: t.indent
80- in
81- t.code < - (String. trim_end ~chars: " " line) :: t.code);
82- in
20+ (* Verify indentation level *)
21+ (match indent with
22+ | `Begin -> incr t
23+ | `End -> decr t
24+ | `EndBegin -> decr t; incr t
25+ | `None -> ()
26+ | `Raw -> ()
27+ );
28+
8329 let emit s =
84- match indent with
85- | `Begin ->
86- prepend s;
87- incr t
88- | `None ->
89- prepend s
90- | `End ->
91- decr t;
92- prepend s
93- | `EndBegin ->
94- decr t;
95- prepend s;
96- incr t
30+ String. split_on_char ~sep: '\n' s
31+ |> List. iter ~f: (fun s -> t.code < - (indent, String. trim_end ~chars: " \t " s) :: t.code)
9732 in
9833 Printf. ksprintf emit fmt
9934
100- let append t code = List. iter ~f: (emit t `None " %s" ) (code.code |> List. rev)
35+ let contents t =
36+ let append buffer indent s =
37+ (match String. length s > 0 with
38+ | true ->
39+ List. iter ~f: (Buffer. add_string buffer) indent;
40+ Buffer. add_string buffer s
41+ | false -> ()
42+ );
43+ Buffer. add_string buffer " \n " ;
44+ buffer
45+ in
46+
47+ let rec print buffer indent = function
48+ | (`None, s ) :: lines -> print (append buffer indent s) indent lines
49+ | (`Begin, s ) :: lines -> print (append buffer indent s) (" " :: indent) lines
50+ | (`EndBegin, s ) :: lines ->
51+ let indent' = List. tl indent in
52+ print (append buffer indent' s) indent lines
53+ | (`End, s ) :: lines ->
54+ let indent = List. tl indent in
55+ print (append buffer indent s) indent lines
56+ | (`Raw, s ) :: lines ->
57+ print (append buffer [] s) indent lines
58+ | [] ->
59+ Buffer. contents buffer
60+ in
61+ print (Buffer. create 256 ) [] (List. rev t.code)
62+
63+ let append t code =
64+ (* Same as rev_append no??? *)
65+ List. iter ~f: (fun l -> t.code < - l :: t.code) (code.code |> List. rev)
10166
10267let append_deprecaton_if ~deprecated level str =
10368 match deprecated with
@@ -110,68 +75,43 @@ let append_deprecaton_if ~deprecated level str =
11075 in
11176 Printf. sprintf " %s[%socaml.alert protobuf \" Marked as deprecated in the .proto file\" ]" str level
11277
113- let append_comments ~comments str =
114- let comment_str =
115- map_comments comments
116- |> String. concat ~sep: " \n "
117- |> String. trim
118- in
119- match List. is_empty comments with
120- | true -> str
121- | false ->
122- Printf. sprintf " %s(** %s *)" str comment_str
123-
12478let emit_deprecation ?(deprecated =true ) t level =
12579 if deprecated then
12680 emit t `None " %s" (append_deprecaton_if ~deprecated: true level " " )
12781
12882let emit_comment ~(position :[`Leading | `Trailing] ) t = function
129- | [] -> ()
130- | comments ->
83+ | None -> ()
84+ | Some comments ->
13185 if position = `Leading then emit t `None " " ;
132- let comments = map_comments comments in
133- let () =
134- match comments with
135- | [ comment ] -> emit t `None " (** %s *)" (String. trim comment)
136- | comments ->
137- emit t `Begin " (**" ;
138- List. iter ~f: (emit t `None " %s" ) comments;
139- emit t `End " *)" ;
140- in
86+ let comment_string = Comment_db. to_ocaml_doc comments in
87+ emit t `Begin " (**" ;
88+ emit t `Raw " %s" comment_string;
89+ emit t `End " *)" ;
14190 if position = `Trailing then emit t `None " " ;
14291 ()
14392
144- let contents t =
145- List. map ~f: (Printf. sprintf " %s" ) (List. rev t.code)
146- |> String. concat ~sep: " \n "
147-
14893(* * Emit comment for muliple fields / constructors *)
14994let emit_field_doc t
15095 ~(position :[`Leading | `Trailing] )
15196 ?(format :('a -> 'b, unit, string, unit) format4="[%s]" )
15297 ?(header =" " )
153- ?(comments = [] )
98+ ?(comments )
15499 param_comments =
155100
156101 (* Remove parameters with no comments *)
157- let param_comments =
158- List. filter ~f: (fun (_ , comments ) -> not (List. is_empty comments)) param_comments
159- in
102+ let has_header = String. length header > 0 in
160103
161- let comments = map_comments comments in
162- match List. exists ~f: (fun s -> String. length s > 0 ) comments, String. length header > 0 , not (List. is_empty param_comments) with
163- | false , _ , false -> ()
164- | has_comments , has_header , _ ->
104+ match comments, List. is_empty param_comments with
105+ | None , true -> ()
106+ | _ ->
165107 if position = `Leading then emit t `None " " ;
166108 emit t `Begin " (**" ;
167-
168- if has_comments then List. iter ~f: (emit t `None " %s" ) comments;
109+ Option. iter ~f: (fun comments -> emit t `Raw " %s" (Comment_db. to_ocaml_doc comments)) comments;
169110 if has_header then emit t `None " %s" header;
170111 List. iter ~f: (fun (param , comments ) ->
171- let comments = map_comments comments in
172112 emit t `None " " ;
173113 emit t `Begin format param;
174- List. iter ~f: ( emit t `None " %s" ) comments;
114+ emit t `Raw " %s" ( Comment_db. to_ocaml_doc comments) ;
175115 emit t `End " " ;
176116 ) param_comments;
177117
0 commit comments