Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 4d953b6

Browse files
Implement pretty outcome printing for uncurried outcometree types (#214)
1 parent 72d9b70 commit 4d953b6

File tree

3 files changed

+371
-41
lines changed

3 files changed

+371
-41
lines changed

src/res_outcome_printer.ml

+67-40
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
module Doc = Res_doc
1111
module Token = Res_token
1212

13+
(* checks if ident contains "arity", like in "arity1", "arity2", "arity3" etc. *)
14+
let isArityIdent ident =
15+
if String.length ident >= 6 then
16+
(String.sub [@doesNotRaise]) ident 0 5 = "arity"
17+
else
18+
false
19+
1320
type identifierStyle =
1421
| ExoticIdent
1522
| NormalIdent
@@ -195,6 +202,21 @@ let printIdentLike ~allowUident txt =
195202
Doc.text " as '";
196203
Doc.text aliasTxt
197204
]
205+
| Otyp_constr (
206+
Oide_dot (Oide_dot (Oide_ident "Js", "Fn") , "arity0"), (* Js.Fn.arity0 *)
207+
[Otyp_constr (Oide_ident ident, [])] (* int or unit or string *)
208+
) ->
209+
(* Js.Fn.arity0<int> -> (.) => int*)
210+
Doc.concat [
211+
Doc.text "(.) => ";
212+
Doc.text ident;
213+
]
214+
| Otyp_constr (
215+
Oide_dot (Oide_dot (Oide_ident "Js", "Fn") , ident), (* Js.Fn.arity2 *)
216+
[(Otyp_arrow _) as arrowType] (* (int, int) => int *)
217+
) when isArityIdent ident ->
218+
(* Js.Fn.arity2<(int, int) => int> -> (. int, int) => int*)
219+
printOutArrowType ~uncurried:true arrowType
198220
| Otyp_constr (outIdent, []) ->
199221
printOutIdentDoc ~allowUident:false outIdent
200222
| Otyp_manifest (typ1, typ2) ->
@@ -283,51 +305,56 @@ let printIdentLike ~allowUident txt =
283305
]
284306
)
285307
| Otyp_arrow _ as typ ->
286-
let (typArgs, typ) = collectArrowArgs typ [] in
287-
let args = Doc.join ~sep:(Doc.concat [Doc.comma; Doc.line]) (
288-
List.map (fun (lbl, typ) ->
289-
if lbl = "" then
290-
printOutTypeDoc typ
291-
else
292-
Doc.group (
293-
Doc.concat [
294-
Doc.text ("~" ^ lbl ^ ": ");
295-
printOutTypeDoc typ
296-
]
297-
)
298-
) typArgs
299-
) in
300-
let argsDoc =
301-
let needsParens = match typArgs with
302-
| [_, (Otyp_tuple _ | Otyp_arrow _)] -> true
303-
(* single argument should not be wrapped *)
304-
| ["", _] -> false
305-
| _ -> true
306-
in
307-
if needsParens then
308+
printOutArrowType ~uncurried:false typ
309+
| Otyp_module (_modName, _stringList, _outTypes) ->
310+
Doc.nil
311+
312+
and printOutArrowType ~uncurried typ =
313+
let (typArgs, typ) = collectArrowArgs typ [] in
314+
let args = Doc.join ~sep:(Doc.concat [Doc.comma; Doc.line]) (
315+
List.map (fun (lbl, typ) ->
316+
if lbl = "" then
317+
printOutTypeDoc typ
318+
else
308319
Doc.group (
309320
Doc.concat [
310-
Doc.lparen;
311-
Doc.indent (
312-
Doc.concat [
313-
Doc.softLine;
314-
args;
315-
]
316-
);
317-
Doc.trailingComma;
318-
Doc.softLine;
319-
Doc.rparen;
321+
Doc.text ("~" ^ lbl ^ ": ");
322+
printOutTypeDoc typ
320323
]
321324
)
322-
else args
325+
) typArgs
326+
) in
327+
let argsDoc =
328+
let needsParens = match typArgs with
329+
| _ when uncurried -> true
330+
| [_, (Otyp_tuple _ | Otyp_arrow _)] -> true
331+
(* single argument should not be wrapped *)
332+
| ["", _] -> false
333+
| _ -> true
323334
in
324-
Doc.concat [
325-
argsDoc;
326-
Doc.text " => ";
327-
printOutTypeDoc typ;
328-
]
329-
| Otyp_module (_modName, _stringList, _outTypes) ->
330-
Doc.nil
335+
if needsParens then
336+
Doc.group (
337+
Doc.concat [
338+
if uncurried then Doc.text "(. " else Doc.lparen;
339+
Doc.indent (
340+
Doc.concat [
341+
Doc.softLine;
342+
args;
343+
]
344+
);
345+
Doc.trailingComma;
346+
Doc.softLine;
347+
Doc.rparen;
348+
]
349+
)
350+
else args
351+
in
352+
Doc.concat [
353+
argsDoc;
354+
Doc.text " => ";
355+
printOutTypeDoc typ;
356+
]
357+
331358

332359
and printOutVariant variant = match variant with
333360
| Ovar_fields fields -> (* (string * bool * out_type list) list *)

tests/oprint/oprint.res

+54
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,57 @@ type exoticUser = {
188188
\"let": string,
189189
\"type": float
190190
}
191+
192+
module Js = {
193+
module Fn = {
194+
type arity0<'a> = {i0: unit => 'a}
195+
type arity1<'a> = {i1: 'a}
196+
type arity2<'a> = {i2: 'a}
197+
type arity3<'a> = {i3: 'a}
198+
type arity4<'a> = {i4: 'a}
199+
type arity5<'a> = {i5: 'a}
200+
type arity6<'a> = {i6: 'a}
201+
type arity7<'a> = {i7: 'a}
202+
type arity8<'a> = {i8: 'a}
203+
type arity9<'a> = {i9: 'a}
204+
type arity10<'a> = {i10: 'a}
205+
type arity11<'a> = {i11: 'a}
206+
type arity12<'a> = {i12: 'a}
207+
type arity13<'a> = {i13: 'a}
208+
type arity14<'a> = {i14: 'a}
209+
type arity15<'a> = {i15: 'a}
210+
type arity16<'a> = {i16: 'a}
211+
type arity17<'a> = {i17: 'a}
212+
type arity18<'a> = {i18: 'a}
213+
type arity19<'a> = {i19: 'a}
214+
type arity20<'a> = {i20: 'a}
215+
type arity21<'a> = {i21: 'a}
216+
type arity22<'a> = {i22: 'a}
217+
}
218+
}
219+
220+
type arity0 = Js.Fn.arity0<unit>
221+
type arity0b = Js.Fn.arity0<int>
222+
type arity1 = Js.Fn.arity1<(int) => int>
223+
type arity2 = Js.Fn.arity2<(int, int) => int>
224+
type arity3 = Js.Fn.arity3<(int, int, int) => int>
225+
type arity4 = Js.Fn.arity4<(int, int, int, int) => int>
226+
type arity5 = Js.Fn.arity5<(int, int, int, int, int) => int>
227+
type arity6 = Js.Fn.arity6<(int, int, int, int, int, int) => int>
228+
type arity7 = Js.Fn.arity7<(int, int, int, int, int, int, int) => int>
229+
type arity8 = Js.Fn.arity8<(int, int, int, int, int, int, int, int) => int>
230+
type arity9 = Js.Fn.arity9<(int, int, int, int, int, int, int, int, int) => int>
231+
type arity10 = Js.Fn.arity10<(int, int, int, int, int, int, int, int, int, int) => int>
232+
type arity11 = Js.Fn.arity11<(int, int, int, int, int, int, int, int, int, int, int) => int>
233+
type arity12 = Js.Fn.arity12<(int, int, int, int, int, int, int, int, int, int, int, int) => int>
234+
type arity13 = Js.Fn.arity13<(int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
235+
type arity14 = Js.Fn.arity14<(int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
236+
type arity15 = Js.Fn.arity15<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
237+
type arity16 = Js.Fn.arity16<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
238+
type arity17 = Js.Fn.arity17<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
239+
type arity18 = Js.Fn.arity18<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
240+
type arity19 = Js.Fn.arity19<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
241+
type arity20 = Js.Fn.arity20<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
242+
type arity21 = Js.Fn.arity21<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
243+
type arity22 = Js.Fn.arity22<(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int) => int>
244+

0 commit comments

Comments
 (0)