123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113(**************************************************************************)(* *)(* OCamlFormat *)(* *)(* Copyright (c) Facebook, Inc. and its affiliates. *)(* *)(* This source code is licensed under the MIT license found in *)(* the LICENSE file in the root directory of this source tree. *)(* *)(**************************************************************************)openExtended_asttype'aitem=|Structure:Extended_ast.structureitem|Signature:Extended_ast.signatureitem|Use_file:Extended_ast.use_fileitemtype'at={attr_loc:Location.t;chunk_loc:Location.t;state:[`Enable|`Disable];items:'alist}letinit_loc=letpos=Lexing.{pos_cnum=0;pos_bol=0;pos_lnum=0;pos_fname=!Location.input_name}inLocation.{loc_ghost=false;loc_start=pos;loc_end=pos}letis_attr(typea)(fg:alistitem)(x:a)=match(fg,x)with|Structure,{pstr_desc=Pstr_attributex;pstr_loc}->Some(x,pstr_loc)|Signature,{psig_desc=Psig_attributex;psig_loc}->Some(x,psig_loc)|Use_file,Ptop_def({pstr_desc=Pstr_attributex;pstr_loc}::_)->Some(x,pstr_loc)|_->Noneletis_state_attrfg~statex=letopenOption.Monad_infixinis_attrfgx>>=fun(attr,loc)->Conf.parse_state_attrattr>>=funnew_state->match(state,new_state)with|`Enable,`Disable->Some(`Disable,loc)|`Disable,`Enable->Some(`Enable,loc)|_->Noneletlast_loc(typea)(fg:alistitem)(l:alist)=letopenOption.Monad_infixinmatchfgwith|Structure->List.lastl>>|funx->x.pstr_loc|Signature->List.lastl>>|funx->x.psig_loc|Use_file->(List.lastl>>=function|Ptop_defx->List.lastx>>|funx->x.pstr_loc|Ptop_dirx->Somex.pdir_loc)letmk~attr_loc~chunk_locstateitems={attr_loc;chunk_loc;state;items}letmk_tmp~locstateitems=mk~attr_loc:loc~chunk_loc:locstateitems(* Build chunks of each disabled/enabled code spans. The [chunk_loc] of each
chunk has an unprecise ending position that needs to be set after looking
at the following chunk. *)letsplit_with_imprecise_locsfg~statel=letinit=([],state)inletchunks,_=List.fold_leftl~init~f:(fun(acc,state)x->matchis_state_attrfg~statexwith|Some(state,loc)->(mk_tmp~locstate[x]::acc,state)|None->(matchaccwith(* first chunk *)|[]->(mk_tmp~loc:init_locstate[x]::acc,state)|chunk::t->({chunkwithitems=x::chunk.items}::t,state)))inList.rev_mapchunks~f:(funx->{xwithitems=List.revx.items})(* Extend the [chunk_loc] to make it span until the start of [last_loc]. *)letextend_end_loc~last_locchunk=letloc_end=last_loc.Location.loc_startinletchunk_loc={chunk.chunk_locwithloc_end}in{chunkwithchunk_loc}(* Update the [chunk_loc] of each chunk by using the loc of the following
chunk. *)letextend_end_locsfgl=matchList.revlwith|[]->[]|h::t->(* last chunk *)letinit=letlast_loc=Option.value(last_locfgh.items)~default:h.chunk_locinletchunk_loc={h.chunk_locwithloc_end=last_loc.loc_end}inleth={hwithchunk_loc}in(h.attr_loc,[h])inlet_,chunks=List.fold_leftt~init~f:(fun(last_loc,acc)chunk->letchunk=extend_end_loc~last_locchunkin(chunk.attr_loc,chunk::acc))inchunksletsplit~statefgl=extend_end_locsfg@@split_with_imprecise_locsfg~statel