Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file reason_heuristics.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140openReason_ompletis_punned_labelled_expressionelbl=letopenAst_411.Parsetreeinmatche.pexp_descwith|Pexp_ident{txt}|Pexp_constraint({pexp_desc=Pexp_ident{txt}},_)|Pexp_coerce({pexp_desc=Pexp_ident{txt}},_,_)->(Reason_syntax_util.parse_lidlbl)=txt|_->false(* We manually check the length of `Thing.map(foo, bar, baz`,
* in `Thing.map(foo, bar, baz, (a) => doStuff(a))`
* because Easyformat doesn't have a hook to change printing when a list breaks
*
* we check if all arguments aside from the final one are either strings or identifiers,
* where the sum of the string contents and identifier names are less than the print width
*)letfunAppCallbackExceedsWidth~printWidth~args~funExpr()=letopenAst_411.ParsetreeinletopenAst_411.AsttypesinletfunLen=beginmatchfunExpr.pexp_descwith|Pexp_identident->letidentList=Longident.flattenident.txtinletlengthOfDots=List.lengthidentList-1inletlen=List.fold_left(funacccurr->acc+(String.lengthcurr))lengthOfDotsidentListinlen|_->-1endin(* eats an argument & substract its length from the printWidth
* as soon as the print width reaches a sub-zero value,
* we know the print width is exceeded & returns *)letrecauxlen=function|_whenlen<0->true|[]->false|arg::args->beginmatchargwith|(label,({pexp_desc=Pexp_identident}ase))->letidentLen=List.fold_left(funacccurr->acc+(String.lengthcurr))len(Longident.flattenident.txt)inbeginmatchlabelwith|Nolabel->aux(len-identLen)args|Labelledswhenis_punned_labelled_expressiones->aux(len-(identLen+1))args|Labelleds->aux(len-(identLen+2+String.lengths))args|Optionals->aux(len-(identLen+3+String.lengths))argsend|(label,{pexp_desc=Pexp_constant(Pconst_string(str,_,_))})->letstrLen=String.lengthstrinbeginmatchlabelwith|Nolabel->aux(len-strLen)args|Labelleds->aux(len-(strLen+2+String.lengths))args|Optionals->aux(len-(strLen+3+String.lengths))argsend|_->(* if we encounter a non-string or non-identifier argument exit *)trueendinaux(printWidth-funLen)args(*
* Whether or not an identiier is small enough to justify omitting the
* trailing comma for single identifier patterns. For single identifier
* patterns, usually the identifier is not "far right" in the document, and
* is one of the last things to require breaking. We can omit the trailing comma
* in these cases because it likely will never render anyways and therefore the
* space taken up by the trailing comma doesn't disrupt wrapping length calculations.
*
* For example, the `X` hardly ever benefits from a trailing comma.
* | X(y) =>
*)letsingleTokenPatternOmmitTrailtxt=String.lengthtxt<4(* Indicates whether an expression can be printed with the uncurried
* dot notation. At the moment uncurried function application & definition
* only makes sense in the context of a Pexp_apply or Pexp_fun
*
* Examples:
* [@bs] add(2, 3); -> add(. 2, 3); (* Pexp_apply *)
* setTimeout([@bs] () => Js.log("hola"), 1000); (* Pexp_fun *)
* -> setTimeout((.) => Js.log("hola"), 1000);
*)letbsExprCanBeUncurriedexpr=matchAst_411.Parsetree.(expr.pexp_desc)with|Pexp_fun_|Pexp_apply_->true|_->falseletisUnderscoreIdentexpr=matchAst_411.Parsetree.(expr.pexp_desc)with|Pexp_ident({txt=Lident"_"})->true|_->falseletisPipeFirste=matchAst_411.Parsetree.(e.pexp_desc)with|Pexp_ident({txt=Longident.Lident("|.")})->true|Pexp_apply({pexp_desc=Pexp_ident({txt=Longident.Lident("|.")})},_)->true|_->falseletisUnderscoreApplicationexpr=letopenAst_411.Parsetreeinmatchexprwith|{pexp_attributes=[];pexp_desc=Pexp_fun(Nolabel,None,{ppat_desc=Ppat_var({txt="__x"});ppat_attributes=[]},_)}->true|_->false(* <div> {items->Belt.Array.map(ReasonReact.string)->ReasonReact.array} </div>;
* An application with pipe first inside jsx children requires special treatment.
* Jsx children don't allow expression application, hence we need the braces
* preserved in this case. *)letisPipeFirstWithNonSimpleJSXChilde=matchAst_411.Parsetree.(e.pexp_desc)with|Pexp_apply({pexp_desc=Pexp_ident({txt=Longident.Lident("|.")})},[Nolabel,{pexp_desc=Pexp_apply(_)};_])->true(* Handle <div> {url->a(b, _)} </div>;
* underscore sugar needs protection *)|Pexp_apply({pexp_desc=Pexp_ident({txt=Longident.Lident("|.")})},[_;Nolabel,fe])whenisUnderscoreApplicationfe->true|_->false