12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736(*_ This file is manually imported from the Jane Street version of the
OCaml compiler. Don't make changes directly to this file. *)[@@@ocaml.warning"-missing-record-field-pattern"]open!Shadow_compiler_distributionopenAsttypesopenJane_asttypesopenParsetreeopenJane_syntax_parsing(** We carefully regulate which bindings we import from [Language_extension]
to ensure that we can import this file into the Jane Street internal
repo with no changes.
*)moduleLanguage_extension=structincludeLanguage_extension_kernelinclude(Language_extension:Language_extension_kernel.Language_extension_for_jane_syntax)end(* Suppress the unused module warning so it's easy to keep around the
shadowing even if we delete use sites of the module. *)module_=Language_extension(****************************************)(* Helpers used just within this module *)moduletypeExtension=sigvalfeature:Feature.tendmoduleAst_of(AST:AST)(Ext:Extension):sig(* Wrap a bit of AST with a jane-syntax annotation *)valwrap_jane_syntax:stringlist->(* these strings describe the bit of new syntax *)?payload:payload->AST.ast->AST.astend=structletwrap_jane_syntaxsuffixes?payloadto_be_wrapped=AST.make_jane_syntaxExt.featuresuffixes?payloadto_be_wrapped;;endmoduleOf_ast(Ext:Extension):sigtypeunwrapped:=stringlist*payload*attributes(* The same as [unwrap_jane_syntax_attributes], except throwing
an exception instead of returning an error.
*)valunwrap_jane_syntax_attributes_exn:loc:Location.t->attributes->unwrappedend=structletextension_string=Feature.extension_componentExt.featuremoduleDesugaring_error=structtypeerror=|Not_this_embeddingofEmbedded_name.t|Non_embeddingletreport_error~loc=function|Not_this_embeddingname->Location.errorf~loc"Tried to desugar the embedded term %a@ as belonging to the %s extension"Embedded_name.pp_quoted_namenameextension_string|Non_embedding->Location.errorf~loc"Tried to desugar a non-embedded expression@ as belonging to the %s extension"extension_string;;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraise~locerr=raise(Error(loc,err))endletunwrap_jane_syntax_attributesattrs:(_,Desugaring_error.error)result=matchfind_and_remove_jane_syntax_attributeattrswith|Some(ext_name,_loc,payload,attrs)->(matchJane_syntax_parsing.Embedded_name.componentsext_namewith|extension_occur::nameswhenString.equalextension_occurextension_string->Ok(names,payload,attrs)|_->Error(Not_this_embeddingext_name))|None->ErrorNon_embedding;;letunwrap_jane_syntax_attributes_exn~locattrs=matchunwrap_jane_syntax_attributesattrswith|Okx->x|Errorerror->Desugaring_error.raise~locerror;;end(******************************************************************************)(** Individual language extension modules *)(* Note [Check for immutable extension in comprehensions code]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When we spot a comprehension for an immutable array, we need to make sure
that both [comprehensions] and [immutable_arrays] are enabled. But our
general mechanism for checking for enabled extensions (in [of_ast]) won't
work well here: it triggers when converting from
e.g. [[%jane.non_erasable.comprehensions.array] ...] to the
comprehensions-specific AST. But if we spot a
[[%jane.non_erasable.comprehensions.immutable]], there is no expression to
translate. So we just check for the immutable arrays extension when
processing a comprehension expression for an immutable array.
Note [Wrapping with make_entire_jane_syntax]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The topmost node in the encoded AST must always look like e.g.
[%jane.non_erasable.comprehensions]. (More generally,
[%jane.ERASABILITY.FEATURE] or [@jane.ERASABILITY.FEATURE].) This allows the
decoding machinery to know what extension is being used and what function to
call to do the decoding. Accordingly, during encoding, after doing the hard
work of converting the extension syntax tree into e.g. Parsetree.expression,
we need to make a final step of wrapping the result in a [%jane.*.xyz] node.
Ideally, this step would be done by part of our general structure, like we
separate [of_ast] and [of_ast_internal] in the decode structure; this design
would make it structurally impossible/hard to forget taking this final step.
However, the final step is only one line of code (a call to
[make_entire_jane_syntax]), but yet the name of the feature varies, as does
the type of the payload. It would thus take several lines of code to execute
this command otherwise, along with dozens of lines to create the structure in
the first place. And so instead we just manually call
[make_entire_jane_syntax] and refer to this Note as a reminder to authors of
future syntax features to remember to do this wrapping.
Note [Outer attributes at end]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The order of attributes matters for several reasons:
- If the user writes attributes on a Jane Street OCaml construct, where
should those appear with respect to the Jane Syntax attribute that
introduces the construct?
- Some Jane Syntax embeddings use attributes, and sometimes an AST node will
have multiple Jane Syntax-related attributes on it. Which attribute should
Jane Syntax interpret first?
Both of these questions are settled by a convention where attributes
appearing later in an attribute list are considered to be "outer" to
attributes appearing earlier. (ppxlib adopted this convention, and thus we
need to as well for compatibility.)
- User-written attributes appear later in the attribute list than
a Jane Syntax attribute that introduces a syntactic construct.
- If multiple Jane Syntax attributes appear on an AST node, the ones
appearing later in the attribute list should be interpreted first.
*)moduletypePayload_protocol=sigtypetmoduleEncode:sigvalas_payload:tloc->payloadvallist_as_payload:tloclist->payloadvaloption_list_as_payload:tlocoptionlist->payloadendmoduleDecode:sigvalfrom_payload:loc:Location.t->payload->tlocvallist_from_payload:loc:Location.t->payload->tloclistvaloption_list_from_payload:loc:Location.t->payload->tlocoptionlistendendmoduletypeStringable=sigtypetvalof_string:string->toptionvalto_string:t->string(** For error messages: a name that can be used to identify the
[t] being converted to and from string, and its indefinite
article (either "a" or "an").
*)valindefinite_article_and_name:string*stringendmoduleMake_payload_protocol_of_stringable(Stringable:Stringable):Payload_protocolwithtypet:=Stringable.t=structmoduleEncode=structletas_exprt_loc=letstring=Stringable.to_stringt_loc.txtinAst_helper.Exp.ident(Location.mkloc(Astlib.Longident.Lidentstring)t_loc.loc);;letstructure_item_of_exprexpr={pstr_desc=Pstr_eval(expr,[]);pstr_loc=Location.none};;letstructure_item_of_none={pstr_desc=Pstr_attribute{attr_name=Location.mknoloc"jane.none";attr_payload=PStr[];attr_loc=Location.none};pstr_loc=Location.none};;letas_payloadt_loc=letexpr=as_exprt_locinPStr[structure_item_of_exprexpr];;letlist_as_payloadt_locs=letitems=List.map(funt_loc->structure_item_of_expr(as_exprt_loc))t_locsinPStritems;;letoption_list_as_payloadt_locs=letitems=List.map(function|None->structure_item_of_none|Somet_loc->structure_item_of_expr(as_exprt_loc))t_locsinPStritems;;endmoduleDesugaring_error=structtypeerror=Unknown_payloadofpayloadletreport_error~loc=function|Unknown_payloadpayload->letindefinite_article,name=Stringable.indefinite_article_and_nameinLocation.errorf~loc"Attribute payload does not name %s %s:@;%a"indefinite_articlename(Printast.payload0)payload;;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraise~locerr=raise(Error(loc,err))endmoduleDecode=struct(* Avoid exporting a definition that raises [Unexpected]. *)openstructexceptionUnexpectedletfrom_expr=function|{pexp_desc=Pexp_identpayload_lid;_}->lett=matchStringable.of_string(Ppxlib.Longident.last_exnpayload_lid.txt)with|None->raiseUnexpected|Somet->tinLocation.mkloctpayload_lid.loc|_->raiseUnexpected;;letexpr_of_structure_item=function|{pstr_desc=Pstr_eval(expr,_)}->expr|_->raiseUnexpected;;letis_none_structure_item=function|{pstr_desc=Pstr_attribute{attr_name={txt="jane.none"}}}->true|_->false;;letfrom_payloadpayload=matchpayloadwith|PStr[item]->from_expr(expr_of_structure_itemitem)|_->raiseUnexpected;;letlist_from_payloadpayload=matchpayloadwith|PStritems->List.map(funitem->from_expr(expr_of_structure_itemitem))items|_->raiseUnexpected;;letoption_list_from_payloadpayload=matchpayloadwith|PStritems->List.map(funitem->ifis_none_structure_itemitemthenNoneelseSome(from_expr(expr_of_structure_itemitem)))items|_->raiseUnexpected;;endletfrom_payload~locpayload:_loc=tryfrom_payloadpayloadwith|Unexpected->Desugaring_error.raise~loc(Unknown_payloadpayload);;letlist_from_payload~locpayload:_list=trylist_from_payloadpayloadwith|Unexpected->Desugaring_error.raise~loc(Unknown_payloadpayload);;letoption_list_from_payload~locpayload:_list=tryoption_list_from_payloadpayloadwith|Unexpected->Desugaring_error.raise~loc(Unknown_payloadpayload);;endendmoduleStringable_const_jkind=structtypet=const_jkindletindefinite_article_and_name="a","layout"letto_string=jkind_to_stringletof_stringt=Some(jkind_of_stringt)endmoduleJkinds_pprint=structletconst_jkindfmtcl=Format_doc.fprintffmt"%s"(Stringable_const_jkind.to_stringcl);;letjkind_annotationfmtann=const_jkindfmtann.txtend(** Jkind annotations' encoding as attribute payload, used in both n-ary
functions and jkinds. *)moduleJkind_annotation:sigincludePayload_protocolwithtypet:=const_jkindmoduleDecode:sigincludemoduletypeofDecodevalbound_vars_from_vars_and_payload:loc:Location.t->stringLocation.loclist->payload->(stringLocation.loc*jkind_annotationoption)listendend=structmoduleProtocol=Make_payload_protocol_of_stringable(Stringable_const_jkind)(*******************************************************)(* Conversions with a payload *)moduleEncode=Protocol.EncodemoduleDecode=structincludeProtocol.DecodemoduleDesugaring_error=structtypeerror=Wrong_number_of_jkindsofint*jkind_annotationoptionlistletreport_error~loc=function|Wrong_number_of_jkinds(n,jkinds)->Location.errorf~loc"Wrong number of layouts in an layout attribute;@;\
expecting %i but got this list:@;\
%a"n(Format_doc.pp_print_list(Format_doc.pp_print_option~none:(funppf()->Format_doc.fprintfppf"None")Jkinds_pprint.jkind_annotation))jkinds;;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraise~locerr=raise(Error(loc,err))endletbound_vars_from_vars_and_payload~locvar_namespayload=letjkinds=option_list_from_payload~locpayloadintryList.combinevar_namesjkindswith(* seems silly to check the length in advance when [combine] does *)|Invalid_argument_->Desugaring_error.raise~loc(Wrong_number_of_jkinds(List.lengthvar_names,jkinds));;endendmoduleMode_expr=structmoduleConst:sigtyperaw=stringtypet=privaterawLocation.locvalmk:string->Location.t->tvallist_as_payload:tlist->payloadvallist_from_payload:loc:Location.t->payload->tlistvalghostify:t->tend=structtyperaw=stringmoduleProtocol=Make_payload_protocol_of_stringable(structtypet=rawletindefinite_article_and_name="a","mode"letto_strings=s(* Ideally, we should check that [s] consists of only alphabet and numbers.
However, this func *)letof_string's=sletof_strings=Some(of_string's)end)letlist_as_payload=Protocol.Encode.list_as_payloadletlist_from_payload=Protocol.Decode.list_from_payloadtypet=rawLocation.locletmktxtloc:t={txt;loc}letghostify{txt;loc}=letloc={locwithloc_ghost=true}in{txt;loc};;endtypet=Const.tlistLocation.locletempty=Location.mknoloc[]letsingletonconst=letconst'=(const:Const.t:>_Location.loc)inLocation.mkloc[const]const'.loc;;letfeature:Feature.t=Language_extensionModeletattribute_components=[]letextension_components=[]letattribute_name=Embedded_name.of_featurefeatureattribute_components|>Embedded_name.to_string;;letextension_name=Embedded_name.of_featurefeatureextension_components|>Embedded_name.to_string;;letpayload_of{txt;_}=matchtxtwith|[]->None|_::_astxt->Some(Const.list_as_payloadtxt);;letof_payload~locpayload=letl=Const.list_from_payload~locpayloadinmatchlwith|[]->Misc.fatal_error"Payload encoding empty mode expression"|_::_->Location.mkloclloc;;letextract_attrattrs=letattrs,rest=List.partition(fun{attr_name;_}->attr_name.txt=attribute_name)attrsinmatchattrswith|[]->None,rest|[attr]->Someattr,rest|_::_::_->Misc.fatal_error"More than one mode attribute";;letof_attr{attr_payload;attr_loc;_}=of_payload~loc:attr_locattr_payloadletmaybe_of_attrsattrs=letattr,rest=extract_attrattrsinletmode=Option.mapof_attrattrinmode,rest;;letof_attrsattrs=letmode,rest=maybe_of_attrsattrsinletmode=Option.valuemode~default:emptyinmode,rest;;letattr_ofmodes=matchpayload_ofmodeswith|None->None|Someattr_payload->letattr_name=Location.mknolocattribute_nameinletattr_loc=modes.locinSome{attr_name;attr_loc;attr_payload};;letghostify{txt;loc}=letloc={locwithloc_ghost=true}inlettxt=List.mapConst.ghostifytxtin{loc;txt};;end(** List and array comprehensions *)moduleComprehensions=structmoduleExt=structletfeature:Feature.t=Language_extensionComprehensionsendmoduleAst_of=Ast_of(Expression)(Ext)moduleOf_ast=Of_ast(Ext)includeExttypeiterator=|Rangeof{start:expression;stop:expression;direction:direction_flag}|Inofexpressiontypeclause_binding={pattern:pattern;iterator:iterator;attributes:attributelist}typeclause=|Forofclause_bindinglist|Whenofexpressiontypecomprehension={body:expression;clauses:clauselist}typeexpression=|Cexp_list_comprehensionofcomprehension|Cexp_array_comprehensionofmutable_flag*comprehension(* The desugared-to-OCaml version of comprehensions is described by the
following BNF, where [{% '...' | expr %}] refers to the result of
[Expression.make_jane_syntax] (via [comprehension_expr]) as described at
the top of [jane_syntax_parsing.mli].
{v
comprehension ::=
| {% 'comprehension.list' | '[' clauses ']' %}
| {% 'comprehension.array' | '[|' clauses '|]' %}
clauses ::=
| {% 'comprehension.for' | 'let' iterator+ 'in' clauses %}
| {% 'comprehension.when' | expr ';' clauses %}
| {% 'comprehension.body' | expr %}
iterator ::=
| pattern '=' {% 'comprehension.for.range.upto' | expr ',' expr %}
| pattern '=' {% 'comprehension.for.range.downto' | expr ',' expr %}
| pattern '=' {% 'comprehension.for.in' | expr %}
v}
*)(** First, we define how to go from the nice AST to the OCaml AST; this is
the [expr_of_...] family of expressions, culminating in
[expr_of_comprehension_expr]. *)letexpr_of_iterator=function|Range{start;stop;direction}->Ast_of.wrap_jane_syntax["for";"range";(matchdirectionwith|Upto->"upto"|Downto->"downto")](Ast_helper.Exp.tuple[start;stop])|Inseq->Ast_of.wrap_jane_syntax["for";"in"]seq;;letexpr_of_clause_binding{pattern;iterator;attributes}=Ast_helper.Vb.mk~attrs:attributespattern(expr_of_iteratoriterator);;letexpr_of_clauseclauserest=matchclausewith|Foriterators->Ast_of.wrap_jane_syntax["for"](Ast_helper.Exp.let_Nonrecursive(List.mapexpr_of_clause_bindingiterators)rest)|Whencond->Ast_of.wrap_jane_syntax["when"](Ast_helper.Exp.sequencecondrest);;letexpr_of_comprehension~type_{body;clauses}=(* We elect to wrap the body in a new AST node (here, [Pexp_lazy])
because it makes it so there is no AST node that can carry multiple Jane
Syntax-related attributes in addition to user-written attributes. This
choice simplifies the definition of [comprehension_expr_of_expr], as
part of its contract is threading through the user-written attributes
on the outermost node.
*)Ast_of.wrap_jane_syntaxtype_(Ast_helper.Exp.lazy_(List.fold_rightexpr_of_clauseclauses(Ast_of.wrap_jane_syntax["body"]body)));;letexpr_of~loccexpr=(* See Note [Wrapping with make_entire_jane_syntax] *)Expression.make_entire_jane_syntax~locfeature(fun()->matchcexprwith|Cexp_list_comprehensioncomp->expr_of_comprehension~type_:["list"]comp|Cexp_array_comprehension(amut,comp)->expr_of_comprehension~type_:["array";(matchamutwith|Mutable->"mutable"|Immutable->"immutable")]comp);;(** Then, we define how to go from the OCaml AST to the nice AST; this is
the [..._of_expr] family of expressions, culminating in
[comprehension_expr_of_expr]. *)moduleDesugaring_error=structtypeerror=|Has_payloadofpayload|Bad_comprehension_embeddingofstringlist|No_clausesletreport_error~loc=function|Has_payloadpayload->Location.errorf~loc"Comprehensions attribute has an unexpected payload:@;%a"(Printast.payload0)payload|Bad_comprehension_embeddingsubparts->Location.errorf~loc"Unknown, unexpected, or malformed@ comprehension embedded term %a"Embedded_name.pp_quoted_name(Embedded_name.of_featurefeaturesubparts)|No_clauses->Location.errorf~loc"Tried to desugar a comprehension with no clauses";;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraiseexprerr=raise(Error(expr.pexp_loc,err))end(* Returns the expression node with the outermost Jane Syntax-related
attribute removed. *)letexpand_comprehension_extension_exprexpr=letnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~loc:expr.pexp_locexpr.pexp_attributesinmatchpayloadwith|PStr[]->names,{exprwithpexp_attributes=attributes}|_->Desugaring_error.raiseexpr(Has_payloadpayload);;letiterator_of_exprexpr=matchexpand_comprehension_extension_exprexprwith|["for";"range";"upto"],{pexp_desc=Pexp_tuple[start;stop];_}->Range{start;stop;direction=Upto}|["for";"range";"downto"],{pexp_desc=Pexp_tuple[start;stop];_}->Range{start;stop;direction=Downto}|["for";"in"],seq->Inseq|bad,_->Desugaring_error.raiseexpr(Bad_comprehension_embeddingbad);;letclause_binding_of_vb{pvb_pat;pvb_expr;pvb_attributes;pvb_loc=_}={pattern=pvb_pat;iterator=iterator_of_exprpvb_expr;attributes=pvb_attributes};;letadd_clauseclausecomp={compwithclauses=clause::comp.clauses}letcomprehension_of_expr=letrecraw_comprehension_of_exprexpr=matchexpand_comprehension_extension_exprexprwith|["for"],{pexp_desc=Pexp_let(Nonrecursive,iterators,rest);_}->add_clause(For(List.mapclause_binding_of_vbiterators))(raw_comprehension_of_exprrest)|["when"],{pexp_desc=Pexp_sequence(cond,rest);_}->add_clause(Whencond)(raw_comprehension_of_exprrest)|["body"],body->{body;clauses=[]}|bad,_->Desugaring_error.raiseexpr(Bad_comprehension_embeddingbad)infunexpr->matchraw_comprehension_of_exprexprwith|{body=_;clauses=[]}->Desugaring_error.raiseexprNo_clauses|comp->comp;;(* Returns remaining unconsumed attributes on outermost expression *)letcomprehension_expr_of_exprexpr=letname,wrapper=expand_comprehension_extension_exprexprinletcomp=matchname,wrapper.pexp_descwith|["list"],Pexp_lazycomp->Cexp_list_comprehension(comprehension_of_exprcomp)|["array";"mutable"],Pexp_lazycomp->Cexp_array_comprehension(Mutable,comprehension_of_exprcomp)|["array";"immutable"],Pexp_lazycomp->(* assert_extension_enabled:
See Note [Check for immutable extension in comprehensions code] *)assert_extension_enabled~loc:expr.pexp_locImmutable_arrays();Cexp_array_comprehension(Immutable,comprehension_of_exprcomp)|bad,_->Desugaring_error.raiseexpr(Bad_comprehension_embeddingbad)incomp,wrapper.pexp_attributes;;end(** Immutable arrays *)moduleImmutable_arrays=structtypenonrecexpression=Iaexp_immutable_arrayofexpressionlisttypenonrecpattern=Iapat_immutable_arrayofpatternlistletfeature:Feature.t=Language_extensionImmutable_arraysletexpr_of~loc=function|Iaexp_immutable_arrayelts->(* See Note [Wrapping with make_entire_jane_syntax] *)Expression.make_entire_jane_syntax~locfeature(fun()->Ast_helper.Exp.arrayelts);;(* Returns remaining unconsumed attributes *)letof_exprexpr=matchexpr.pexp_descwith|Pexp_arrayelts->Iaexp_immutable_arrayelts,expr.pexp_attributes|_->failwith"Malformed immutable array expression";;letpat_of~loc=function|Iapat_immutable_arrayelts->(* See Note [Wrapping with make_entire_jane_syntax] *)Pattern.make_entire_jane_syntax~locfeature(fun()->Ast_helper.Pat.arrayelts);;(* Returns remaining unconsumed attributes *)letof_patpat=matchpat.ppat_descwith|Ppat_arrayelts->Iapat_immutable_arrayelts,pat.ppat_attributes|_->failwith"Malformed immutable array pattern";;endmoduleN_ary_functions=structmoduleExt=structletfeature:Feature.t=BuiltinendmoduleAst_of=Ast_of(Expression)(Ext)moduleOf_ast=Of_ast(Ext)typefunction_param_desc=|Pparam_valofarg_label*expressionoption*pattern|Pparam_newtypeofstringloc*jkind_annotationoptionletfunction_param_desc_of_parsetree:Parsetree.function_param_desc->function_param_desc=function|Pparam_val(lbl,def,pat)->Pparam_val(lbl,def,pat)|Pparam_newtypetv->Pparam_newtype(tv,None)letfunction_param_desc_to_parsetree:function_param_desc->Parsetree.function_param_desc=function|Pparam_val(lbl,def,pat)->Pparam_val(lbl,def,pat)|Pparam_newtype(tv,_jkind)->Pparam_newtypetvtypefunction_param={pparam_desc:function_param_desc;pparam_loc:Location.t}letfunction_param_of_parsetree:Parsetree.function_param->function_param=funpparam->{pparam_desc=function_param_desc_of_parsetreepparam.pparam_desc;pparam_loc=pparam.pparam_loc}letfunction_param_to_parsetree:function_param->Parsetree.function_param=funpparam->{pparam_desc=function_param_desc_to_parsetreepparam.pparam_desc;pparam_loc=pparam.pparam_loc}typefunction_constraint={mode_annotations:Mode_expr.t;type_constraint:Parsetree.type_constraint}letfunction_constraint_of_parsetree:Parsetree.type_constraint->function_constraint=funtype_constraint->{mode_annotations=Mode_expr.empty;type_constraint}letfunction_constraint_to_parsetree:function_constraint->Parsetree.type_constraint=funconstr->constr.type_constrainttypeexpression=function_paramlist*function_constraintoption*function_bodyletof_exprexpr=matchexpr.pexp_descwith|Pexp_function(params,constr,body)->Some((List.mapfunction_param_of_parsetreeparams,Option.mapfunction_constraint_of_parsetreeconstr,body),expr.pexp_attributes)|_->Noneletexpr_of~loc(params,constraint_,body)=letpexp_desc=Pexp_function(List.mapfunction_param_to_parsetreeparams,Option.mapfunction_constraint_to_parsetreeconstraint_,body)in{pexp_desc;pexp_loc=loc;pexp_loc_stack=[];pexp_attributes=[]}end(** Labeled tuples *)moduleLabeled_tuples=structmoduleExt=structletfeature:Feature.t=Language_extensionLabeled_tuplesendmoduleOf_ast=Of_ast(Ext)includeExttypenonreccore_type=(stringoption*core_type)listtypenonrecexpression=(stringoption*expression)listtypenonrecpattern=(stringoption*pattern)list*closed_flagletstring_of_label=function|None->""|Somelbl->lbl;;letlabel_of_string=function|""->None|s->Somes;;letstring_of_closed_flag=function|Closed->"closed"|Open->"open";;letclosed_flag_of_string=function|"closed"->Closed|"open"->Open|_->failwith"bad closed flag";;moduleDesugaring_error=structtypeerror=|Malformed|Has_payloadofpayloadletreport_error~loc=function|Malformed->Location.errorf~loc"Malformed embedded labeled tuple term"|Has_payloadpayload->Location.errorf~loc"Labeled tuples attribute has an unexpected payload:@;%a"(Printast.payload0)payload;;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraiselocerr=raise(Error(loc,err))endletexpand_labeled_tuple_extensionlocattrs=letnames,payload,attrs=Of_ast.unwrap_jane_syntax_attributes_exn~locattrsinmatchpayloadwith|PStr[]->names,attrs|_->Desugaring_error.raiseloc(Has_payloadpayload);;type'alabel_check_result=|No_labelsof'alist|At_least_one_labelof(stringoption*'a)listletcheck_for_any_labelxs=ifList.for_all(fun(lbl,_x)->Option.is_nonelbl)xsthenNo_labels(List.mapsndxs)elseAt_least_one_labelxs;;lettyp_of~loctl=matchcheck_for_any_labeltlwith|No_labelstl->Ast_helper.Typ.tuple~loctl|At_least_one_labeltl->(* See Note [Wrapping with make_entire_jane_syntax] *)Core_type.make_entire_jane_syntax~locfeature(fun()->letnames=List.map(fun(label,_)->string_of_labellabel)tlinCore_type.make_jane_syntaxfeaturenames@@Ast_helper.Typ.tuple(List.mapsndtl));;(* Returns remaining unconsumed attributes *)letof_typtyp=letlabels,ptyp_attributes=expand_labeled_tuple_extensiontyp.ptyp_loctyp.ptyp_attributesinmatchtyp.ptyp_descwith|Ptyp_tuplecomponents->ifList.lengthlabels<>List.lengthcomponentsthenDesugaring_error.raisetyp.ptyp_locMalformed;letlabeled_components=List.map2(funst->label_of_strings,t)labelscomponentsinlabeled_components,ptyp_attributes|_->Desugaring_error.raisetyp.ptyp_locMalformed;;letexpr_of~locel=matchcheck_for_any_labelelwith|No_labelsel->Ast_helper.Exp.tuple~locel|At_least_one_labelel->(* See Note [Wrapping with make_entire_jane_syntax] *)Expression.make_entire_jane_syntax~locfeature(fun()->letnames=List.map(fun(label,_)->string_of_labellabel)elinExpression.make_jane_syntaxfeaturenames@@Ast_helper.Exp.tuple(List.mapsndel));;(* Returns remaining unconsumed attributes *)letof_exprexpr=letlabels,pexp_attributes=expand_labeled_tuple_extensionexpr.pexp_locexpr.pexp_attributesinmatchexpr.pexp_descwith|Pexp_tuplecomponents->ifList.lengthlabels<>List.lengthcomponentsthenDesugaring_error.raiseexpr.pexp_locMalformed;letlabeled_components=List.map2(funse->label_of_strings,e)labelscomponentsinlabeled_components,pexp_attributes|_->Desugaring_error.raiseexpr.pexp_locMalformed;;letpat_of=letmake_jane_syntax~locplclosed=(* See Note [Wrapping with make_entire_jane_syntax] *)Pattern.make_entire_jane_syntax~locfeature(fun()->letnames=List.map(fun(label,_)->string_of_labellabel)plinPattern.make_jane_syntaxfeature(string_of_closed_flagclosed::names)@@Ast_helper.Pat.tuple(List.mapsndpl))infun~loc(pl,closed)->matchclosedwith|Open->make_jane_syntax~locplclosed|Closed->(matchcheck_for_any_labelplwith|No_labelspl->Ast_helper.Pat.tuple~locpl|At_least_one_labelpl->make_jane_syntax~locplclosed);;(* Returns remaining unconsumed attributes *)letof_patpat=letlabels,ppat_attributes=expand_labeled_tuple_extensionpat.ppat_locpat.ppat_attributesinmatchlabels,pat.ppat_descwith|closed::labels,Ppat_tuplecomponents->ifList.lengthlabels<>List.lengthcomponentsthenDesugaring_error.raisepat.ppat_locMalformed;letclosed=closed_flag_of_stringclosedinletlabeled_components=List.map2(funse->label_of_strings,e)labelscomponentsin(labeled_components,closed),ppat_attributes|_->Desugaring_error.raisepat.ppat_locMalformed;;end(** [include functor] *)moduleInclude_functor=structtypesignature_item=Ifsig_include_functorofinclude_descriptiontypestructure_item=Ifstr_include_functorofinclude_declarationletfeature:Feature.t=Language_extensionInclude_functorletsig_item_of~loc=function|Ifsig_include_functorincl->(* See Note [Wrapping with make_entire_jane_syntax] *)Signature_item.make_entire_jane_syntax~locfeature(fun()->Ast_helper.Sig.include_incl);;letof_sig_itemsigi=matchsigi.psig_descwith|Psig_includeincl->Ifsig_include_functorincl|_->failwith"Malformed [include functor] in signature";;letstr_item_of~loc=function|Ifstr_include_functorincl->(* See Note [Wrapping with make_entire_jane_syntax] *)Structure_item.make_entire_jane_syntax~locfeature(fun()->Ast_helper.Str.include_incl);;letof_str_itemstri=matchstri.pstr_descwith|Pstr_includeincl->Ifstr_include_functorincl|_->failwith"Malformed [include functor] in structure";;end(** Module strengthening *)moduleStrengthen=structtypenonrecmodule_type={mty:Parsetree.module_type;mod_id:Astlib.Longident.tLocation.loc}letfeature:Feature.t=Language_extensionModule_strengthening(* Encoding: [S with M] becomes [functor (_ : S) -> (module M)], where
the [(module M)] is a [Pmty_alias]. This isn't syntax we can write, but
[(module M)] can be the inferred type for [M], so this should be fine. *)letmty_of~loc{mty;mod_id}=(* See Note [Wrapping with make_entire_jane_syntax] *)Module_type.make_entire_jane_syntax~locfeature(fun()->Ast_helper.Mty.functor_(Named(Location.mknolocNone,mty))(Ast_helper.Mty.aliasmod_id));;(* Returns remaining unconsumed attributes *)letof_mtymty=matchmty.pmty_descwith|Pmty_functor(Named(_,mty),{pmty_desc=Pmty_aliasmod_id})->{mty;mod_id},mty.pmty_attributes|_->failwith"Malformed strengthened module type";;end(** Layouts *)moduleLayouts=structmoduleExt=structletfeature:Feature.t=Language_extensionLayoutsendincludeExtmoduleOf_ast=Of_ast(Ext)typeconstant=|Floatofstring*charoption|Integerofstring*chartypenonrecexpression=|Lexp_constantofconstant|Lexp_newtypeofstringloc*jkind_annotation*expressiontypenonrecpattern=Lpat_constantofconstanttypenonreccore_type=|Ltyp_varof{name:stringoption;jkind:jkind_annotation}|Ltyp_polyof{bound_vars:(stringloc*jkind_annotationoption)list;inner_type:core_type}|Ltyp_aliasof{aliased_type:core_type;name:stringoption;jkind:jkind_annotation}typenonrecextension_constructor=|Lext_declof(stringLocation.loc*jkind_annotationoption)list*constructor_arguments*Parsetree.core_typeoption(*******************************************************)(* Pretty-printing *)modulePprint=Jkinds_pprint(*******************************************************)(* Errors *)moduleDesugaring_error=structtypeerror=|Unexpected_wrapped_typeofParsetree.core_type|Unexpected_wrapped_extofParsetree.extension_constructor|Unexpected_attributeofstringlist|No_integer_suffix|Unexpected_constantofParsetree.constant|Unexpected_wrapped_exprofParsetree.expression|Unexpected_wrapped_patofParsetree.pattern(* Most things here are unprintable because we can't reference any
[Printast] functions that aren't exposed by the upstream compiler, as we
want this file to be compatible with the upstream compiler; see Note
[Buildable with upstream] in jane_syntax.mli for details. *)letreport_error~loc=function|Unexpected_wrapped_type_typ->Location.errorf~loc"Layout attribute on wrong core type"|Unexpected_wrapped_ext_ext->Location.errorf~loc"Layout attribute on wrong extension constructor"|Unexpected_attributenames->Location.errorf~loc"Layout extension does not understand these attribute names:@;[%a]"(Format_doc.pp_print_list~pp_sep:(funppf()->Format_doc.fprintfppf";@ ")Format_doc.pp_print_text)names|No_integer_suffix->Location.errorf~loc"All unboxed integers require a suffix to determine their size."|Unexpected_constant_c->Location.errorf~loc"Unexpected unboxed constant"|Unexpected_wrapped_exprexpr->Location.errorf~loc"Layout attribute on wrong expression:@;%a"(Printast.expression0)expr|Unexpected_wrapped_pat_pat->Location.errorf~loc"Layout attribute on wrong pattern";;exceptionErrorofLocation.t*errorlet()=Location.register_error_of_exn(function|Error(loc,err)->Some(report_error~locerr)|_->None);;letraise~locerr=raise(Error(loc,err))endmoduleEncode=Jkind_annotation.EncodemoduleDecode=Jkind_annotation.Decode(*******************************************************)(* Constants *)letconstant_of=function|Float(x,suffix)->Pconst_float(x,suffix)|Integer(x,suffix)->Pconst_integer(x,Somesuffix);;letof_constant~loc=function|Pconst_float(x,suffix)->Float(x,suffix)|Pconst_integer(x,Somesuffix)->Integer(x,suffix)|Pconst_integer(_,None)->Desugaring_error.raise~locNo_integer_suffix|const->Desugaring_error.raise~loc(Unexpected_constantconst);;(*******************************************************)(* Encoding expressions *)letexpr_of~locexpr=letmoduleAst_of=Ast_of(Expression)(Ext)in(* See Note [Wrapping with make_entire_jane_syntax] *)Expression.make_entire_jane_syntax~locfeature(fun()->matchexprwith|Lexp_constantc->letconstant=constant_ofcinAst_of.wrap_jane_syntax["unboxed"]@@Ast_helper.Exp.constantconstant|Lexp_newtype(name,jkind,inner_expr)->letpayload=Encode.as_payloadjkindinAst_of.wrap_jane_syntax["newtype"]~payload@@Ast_helper.Exp.newtypenameinner_expr);;(*******************************************************)(* Desugaring expressions *)letof_exprexpr=letloc=expr.pexp_locinletnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~locexpr.pexp_attributesinletlexpr=matchnameswith|["unboxed"]->(matchexpr.pexp_descwith|Pexp_constantconst->Lexp_constant(of_constant~locconst)|_->Desugaring_error.raise~loc(Unexpected_wrapped_exprexpr))|["newtype"]->letjkind=Decode.from_payload~locpayloadin(matchexpr.pexp_descwith|Pexp_newtype(name,inner_expr)->Lexp_newtype(name,jkind,inner_expr)|_->Desugaring_error.raise~loc(Unexpected_wrapped_exprexpr))|_->Desugaring_error.raise~loc(Unexpected_attributenames)inlexpr,attributes;;(*******************************************************)(* Encoding patterns *)letpat_of~loct=Pattern.make_entire_jane_syntax~locfeature(fun()->matchtwith|Lpat_constantc->letconstant=constant_ofcinAst_helper.Pat.constantconstant);;(*******************************************************)(* Desugaring patterns *)letof_patpat=letloc=pat.ppat_locinletlpat=matchpat.ppat_descwith|Ppat_constantconst->Lpat_constant(of_constant~locconst)|_->Desugaring_error.raise~loc(Unexpected_wrapped_patpat)inlpat,pat.ppat_attributes;;(*******************************************************)(* Encoding types *)moduleType_of=Ast_of(Core_type)(Ext)lettype_of~loctyp=letexceptionNo_wrap_necessaryofParsetree.core_typeintry(* See Note [Wrapping with make_entire_jane_syntax] *)Core_type.make_entire_jane_syntax~locfeature(fun()->matchtypwith|Ltyp_var{name;jkind}->letpayload=Encode.as_payloadjkindinType_of.wrap_jane_syntax["var"]~payload@@(matchnamewith|None->Ast_helper.Typ.any~loc()|Somename->Ast_helper.Typ.var~locname)|Ltyp_poly{bound_vars;inner_type}->letvar_names,jkinds=List.splitbound_varsin(* Pass the loc because we don't want a ghost location here *)lettpoly=Ast_helper.Typ.poly~locvar_namesinner_typeinifList.for_allOption.is_nonejkindsthenraise(No_wrap_necessarytpoly)else(letpayload=Encode.option_list_as_payloadjkindsinType_of.wrap_jane_syntax["poly"]~payloadtpoly)|Ltyp_alias{aliased_type;name;jkind}->letpayload=Encode.as_payloadjkindinlethas_name,inner_typ=matchnamewith|None->"anon",aliased_type|Somename->"named",Ast_helper.Typ.aliasaliased_type(Location.mklocnameloc)inType_of.wrap_jane_syntax["alias";has_name]~payloadinner_typ)with|No_wrap_necessaryresult_type->result_type;;(*******************************************************)(* Desugaring types *)letof_typetyp=letloc=typ.ptyp_locinletnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~loctyp.ptyp_attributesinletlty=matchnameswith|["var"]->letjkind=Decode.from_payload~locpayloadin(matchtyp.ptyp_descwith|Ptyp_any->Ltyp_var{name=None;jkind}|Ptyp_varname->Ltyp_var{name=Somename;jkind}|_->Desugaring_error.raise~loc(Unexpected_wrapped_typetyp))|["poly"]->(matchtyp.ptyp_descwith|Ptyp_poly(var_names,inner_type)->letbound_vars=Decode.bound_vars_from_vars_and_payload~locvar_namespayloadinLtyp_poly{bound_vars;inner_type}|_->Desugaring_error.raise~loc(Unexpected_wrapped_typetyp))|["alias";"anon"]->letjkind=Decode.from_payload~locpayloadinLtyp_alias{aliased_type={typwithptyp_attributes=attributes};name=None;jkind}|["alias";"named"]->letjkind=Decode.from_payload~locpayloadin(matchtyp.ptyp_descwith|Ptyp_alias(inner_typ,name)->Ltyp_alias{aliased_type=inner_typ;name=Somename.txt;jkind}|_->Desugaring_error.raise~loc(Unexpected_wrapped_typetyp))|_->Desugaring_error.raise~loc(Unexpected_attributenames)inlty,attributes;;(*******************************************************)(* Encoding extension constructor *)moduleExt_ctor_of=Ast_of(Extension_constructor)(Ext)letextension_constructor_of~loc~name?info?docsext=(* using optional parameters to hook into existing defaulting
in [Ast_helper.Te.decl], which seems unwise to duplicate *)letexceptionNo_wrap_necessaryofParsetree.extension_constructorintry(* See Note [Wrapping with make_entire_jane_syntax] *)Extension_constructor.make_entire_jane_syntax~locfeature(fun()->matchextwith|Lext_decl(bound_vars,args,res)->letvars,jkinds=List.splitbound_varsinletext_ctor=(* Pass ~loc here, because the constructor declaration is
not a ghost *)Ast_helper.Te.decl~loc~vars~args?info?docs?resnameinifList.for_allOption.is_nonejkindsthenraise(No_wrap_necessaryext_ctor)else(letpayload=Encode.option_list_as_payloadjkindsinExt_ctor_of.wrap_jane_syntax["ext"]~payloadext_ctor))with|No_wrap_necessaryext_ctor->ext_ctor;;(*******************************************************)(* Desugaring extension constructor *)letof_extension_constructorext=letloc=ext.pext_locinletnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~locext.pext_attributesinletlext=matchnameswith|["ext"]->(matchext.pext_kindwith|Pext_decl(var_names,args,res)->letbound_vars=Decode.bound_vars_from_vars_and_payload~locvar_namespayloadinLext_decl(bound_vars,args,res)|_->Desugaring_error.raise~loc(Unexpected_wrapped_extext))|_->Desugaring_error.raise~loc(Unexpected_attributenames)inlext,attributes;;(*********************************************************)(* Constructing a [constructor_declaration] with jkinds *)moduleCtor_decl_of=Ast_of(Constructor_declaration)(Ext)letconstructor_declaration_of~loc~attrs~info~vars_jkinds~args~resname=letvars,jkinds=List.splitvars_jkindsinletctor_decl=Ast_helper.Type.constructor~loc~info~vars~args?resnameinletctor_decl=ifList.for_allOption.is_nonejkindsthenctor_declelse(letpayload=Encode.option_list_as_payloadjkindsinConstructor_declaration.make_entire_jane_syntax~locfeature(fun()->Ctor_decl_of.wrap_jane_syntax["vars"]~payloadctor_decl))in(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->ctor_decl|_::_asattrs->(* See Note [Outer attributes at end] *){ctor_declwithpcd_attributes=ctor_decl.pcd_attributes@attrs};;letof_constructor_declaration_internal(feat:Feature.t)ctor_decl=matchfeatwith|Language_extensionLayouts->letloc=ctor_decl.pcd_locinletnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~locctor_decl.pcd_attributesinletvars_jkinds=matchnameswith|["vars"]->Decode.bound_vars_from_vars_and_payload~locctor_decl.pcd_varspayload|_->Desugaring_error.raise~loc(Unexpected_attributenames)inSome(vars_jkinds,attributes)|_->None;;letof_constructor_declaration=Constructor_declaration.make_of_ast~of_ast_internal:of_constructor_declaration_internal;;(*********************************************************)(* Constructing a [type_declaration] with jkinds *)moduleType_decl_of=Ast_of(Type_declaration)(Ext)lettype_declaration_of~loc~attrs~docs~text~params~cstrs~kind~priv~manifest~jkindname=lettype_decl=Ast_helper.Type.mk~loc~docs?text~params~cstrs~kind~priv?manifestnameinlettype_decl=matchjkindwith|None->type_decl|Somejkind->Type_declaration.make_entire_jane_syntax~locfeature(fun()->letpayload=Encode.as_payloadjkindinType_decl_of.wrap_jane_syntax["annot"]~payloadtype_decl)in(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->type_decl|_::_asattrs->(* See Note [Outer attributes at end] *){type_declwithptype_attributes=type_decl.ptype_attributes@attrs};;letof_type_declaration_internal(feat:Feature.t)type_decl=matchfeatwith|Language_extensionLayouts->letloc=type_decl.ptype_locinletnames,payload,attributes=Of_ast.unwrap_jane_syntax_attributes_exn~loctype_decl.ptype_attributesinletjkind_annot=matchnameswith|["annot"]->Decode.from_payload~locpayload|_->Desugaring_error.raise~loc(Unexpected_attributenames)inSome(jkind_annot,attributes)|_->None;;letof_type_declaration=Type_declaration.make_of_ast~of_ast_internal:of_type_declaration_internal;;end(******************************************************************************)(** The interface to our novel syntax, which we export *)moduletypeAST=sigtypettypeastvalof_ast:ast->toptionendmoduleCore_type=structtypet=|Jtyp_layoutofLayouts.core_type|Jtyp_tupleofLabeled_tuples.core_typeletof_ast_internal(feat:Feature.t)typ=matchfeatwith|Language_extensionLayouts->lettyp,attrs=Layouts.of_typetypinSome(Jtyp_layouttyp,attrs)|Language_extensionLabeled_tuples->lettyp,attrs=Labeled_tuples.of_typtypinSome(Jtyp_tupletyp,attrs)|_->None;;letof_ast=Core_type.make_of_ast~of_ast_internalletcore_type_of~loc~attrst=letcore_type=matchtwith|Jtyp_layoutx->Layouts.type_of~locx|Jtyp_tuplex->Labeled_tuples.typ_of~locxin(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->core_type|_::_asattrs->(* See Note [Outer attributes at end] *){core_typewithptyp_attributes=core_type.ptyp_attributes@attrs};;endmoduleConstructor_argument=structtypet=|letof_ast_internal(feat:Feature.t)_carg=matchfeatwith|_->None;;letof_ast=Constructor_argument.make_of_ast~of_ast_internalendmoduleExpression=structtypet=|Jexp_comprehensionofComprehensions.expression|Jexp_immutable_arrayofImmutable_arrays.expression|Jexp_layoutofLayouts.expression|Jexp_n_ary_functionofN_ary_functions.expression|Jexp_tupleofLabeled_tuples.expressionletof_ast_internal(feat:Feature.t)expr=matchfeatwith|Language_extensionComprehensions->letexpr,attrs=Comprehensions.comprehension_expr_of_exprexprinSome(Jexp_comprehensionexpr,attrs)|Language_extensionImmutable_arrays->letexpr,attrs=Immutable_arrays.of_exprexprinSome(Jexp_immutable_arrayexpr,attrs)|Language_extensionLayouts->letexpr,attrs=Layouts.of_exprexprinSome(Jexp_layoutexpr,attrs)|Builtin->(matchN_ary_functions.of_exprexprwith|Some(expr,attrs)->Some(Jexp_n_ary_functionexpr,attrs)|None->None)|Language_extensionLabeled_tuples->letexpr,attrs=Labeled_tuples.of_exprexprinSome(Jexp_tupleexpr,attrs)|_->None;;letof_ast=Expression.make_of_ast~of_ast_internalletexpr_of~loc~attrst=letexpr=matchtwith|Jexp_comprehensionx->Comprehensions.expr_of~locx|Jexp_immutable_arrayx->Immutable_arrays.expr_of~locx|Jexp_layoutx->Layouts.expr_of~locx|Jexp_n_ary_functionx->N_ary_functions.expr_of~locx|Jexp_tuplex->Labeled_tuples.expr_of~locxin(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->expr|_::_asattrs->(* See Note [Outer attributes at end] *){exprwithpexp_attributes=expr.pexp_attributes@attrs};;endmodulePattern=structtypet=|Jpat_immutable_arrayofImmutable_arrays.pattern|Jpat_layoutofLayouts.pattern|Jpat_tupleofLabeled_tuples.patternletof_ast_internal(feat:Feature.t)pat=matchfeatwith|Language_extensionImmutable_arrays->letexpr,attrs=Immutable_arrays.of_patpatinSome(Jpat_immutable_arrayexpr,attrs)|Language_extensionLayouts->letpat,attrs=Layouts.of_patpatinSome(Jpat_layoutpat,attrs)|Language_extensionLabeled_tuples->letexpr,attrs=Labeled_tuples.of_patpatinSome(Jpat_tupleexpr,attrs)|_->None;;letof_ast=Pattern.make_of_ast~of_ast_internalletpat_of~loc~attrst=letpat=matchtwith|Jpat_immutable_arrayx->Immutable_arrays.pat_of~locx|Jpat_layoutx->Layouts.pat_of~locx|Jpat_tuplex->Labeled_tuples.pat_of~locxin(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->pat|_::_asattrs->(* See Note [Outer attributes at end] *){patwithppat_attributes=pat.ppat_attributes@attrs};;endmoduleModule_type=structtypet=Jmty_strengthenofStrengthen.module_typeletof_ast_internal(feat:Feature.t)mty=matchfeatwith|Language_extensionModule_strengthening->letmty,attrs=Strengthen.of_mtymtyinSome(Jmty_strengthenmty,attrs)|_->None;;letof_ast=Module_type.make_of_ast~of_ast_internalletmty_of~loc~attrst=letmty=matchtwith|Jmty_strengthenx->Strengthen.mty_of~locxin(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->mty|_::_asattrs->(* See Note [Outer attributes at end] *){mtywithpmty_attributes=mty.pmty_attributes@attrs};;endmoduleSignature_item=structtypet=Jsig_include_functorofInclude_functor.signature_itemletof_ast_internal(feat:Feature.t)sigi=matchfeatwith|Language_extensionInclude_functor->Some(Jsig_include_functor(Include_functor.of_sig_itemsigi))|_->None;;letof_ast=Signature_item.make_of_ast~of_ast_internalendmoduleStructure_item=structtypet=Jstr_include_functorofInclude_functor.structure_itemletof_ast_internal(feat:Feature.t)stri=matchfeatwith|Language_extensionInclude_functor->Some(Jstr_include_functor(Include_functor.of_str_itemstri))|_->None;;letof_ast=Structure_item.make_of_ast~of_ast_internalendmoduleExtension_constructor=structtypet=Jext_layoutofLayouts.extension_constructorletof_ast_internal(feat:Feature.t)ext=matchfeatwith|Language_extensionLayouts->letext,attrs=Layouts.of_extension_constructorextinSome(Jext_layoutext,attrs)|_->None;;letof_ast=Extension_constructor.make_of_ast~of_ast_internalletextension_constructor_of~loc~name~attrs?info?docst=letext_ctor=matchtwith|Jext_layoutlext->Layouts.extension_constructor_of~loc~name?info?docslextin(* Performance hack: save an allocation if [attrs] is empty. *)matchattrswith|[]->ext_ctor|_::_asattrs->(* See Note [Outer attributes at end] *){ext_ctorwithpext_attributes=ext_ctor.pext_attributes@attrs};;end