123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286openPpxlibmoduleBuilder=Ast_builder.Defaulttypetarget=Native|Jsletmode=refNativemodulePlatform=structletpattern=Ast_pattern.(__')letcollect_expressions~locfirstsecond=match(first.pc_lhs.ppat_desc,second.pc_lhs.ppat_desc)with|(Ppat_construct({txt=Lident"Server"|Ldot(Lident"Runtime","Server");_},_),Ppat_construct({txt=Lident"Client"|Ldot(Lident"Runtime","Client");_},_))->Ok(first.pc_rhs,second.pc_rhs)|(Ppat_construct({txt=Lident"Client"|Ldot(Lident"Runtime","Client");_},_),Ppat_construct({txt=Lident"Server"|Ldot(Lident"Runtime","Server");_},_))->Ok(second.pc_rhs,first.pc_rhs)|_->Error[%expr[%ocaml.error"[browser_only] switch%%platform requires 2 cases: `Server` and \
`Client`"]]letswitch_platform_requires_a_match~loc=[%expr[%ocaml.error"[browser_ppx] switch%%platform requires a match expression"]]lethandler~ctxt:_{txt=payload;loc}=matchpayloadwith|PStr[{pstr_desc=Pstr_eval(expression,_);_}]->(matchexpression.pexp_descwith|Pexp_match(_expression,cases)->(matchcaseswith|[first;second]->(matchcollect_expressions~locfirstsecondwith|Ok(server_expr,client_expr)->(match!modewith(* When it's -js keep the client_expr *)|Js->client_expr(* When it's isn't -js keep the server_expr *)|Native->server_expr)|Errorerror_msg_expr->error_msg_expr)|_->switch_platform_requires_a_match~loc)|_->switch_platform_requires_a_match~loc)|_->switch_platform_requires_a_match~locletrule=Context_free.Rule.extension(Extension.V3.declare"platform"Extension.Context.expressionpatternhandler)endletremove_type_constraintpattern=matchpatternwith|{ppat_desc=Ppat_constraint(pattern,_);_}->pattern|_->patternletreclast_expr_to_raise_impossible~locoriginal_nameexpr=matchexpr.pexp_descwith|Pexp_constraint(expr,_)->last_expr_to_raise_impossible~locoriginal_nameexpr|Pexp_fun(arg_label,_arg_expression,fun_pattern,expression)->letnew_fun_pattern=remove_type_constraintfun_patterninletfn=Builder.pexp_fun~locarg_labelNonenew_fun_pattern(last_expr_to_raise_impossible~locoriginal_nameexpression)in{fnwithpexp_attributes=expr.pexp_attributes}|_->[%exprRuntime.fail_impossible_action_in_ssr[%eBuilder.estring~locoriginal_name]]moduleBrowser_only=structletget_function_namepattern=matchpatternwithPpat_var{txt=name;_}->name|_->"<unkwnown>"leterror_only_works_on~loc=[%expr[%ocaml.error"[browser_ppx] browser_only works on function definitions or values. \
If there's another case where it can be helpful, feel free to open an \
issue in https://github.com/ml-in-barcelona/server-reason-react."]]letremove_alert_browser_only~loc=Builder.attribute~loc~name:{txt="alert";loc}~payload:(PStr[[%stri"-browser_only"]])letbrowser_only_fun~locarg_labelpatternexpression=letstringified=Ppxlib.Pprintast.string_of_expressionexpressioninletmessage=Builder.estring~locstringifiedinletfn=Builder.pexp_fun~locarg_labelNonepattern[%exprRuntime.fail_impossible_action_in_ssr[%emessage]]in{fnwithpexp_attributes=expression.pexp_attributes}letbrowser_only_value_bindingpatternexpression=letloc=pattern.ppat_locinmatchpatternwith|[%pat?()]->Builder.value_binding~loc~pat:pattern~expr:[%expr()]|_->(matchexpression.pexp_descwith|Pexp_constraint({pexp_desc=Pexp_fun(_arg_label,_arg_expression,_fun_pattern,_expr);_;},_type_constraint)->letfunction_name=get_function_namepattern.ppat_descinletexpr=last_expr_to_raise_impossible~locfunction_nameexpressioninletvb=Builder.value_binding~loc~pat:pattern~exprin{vbwithpvb_attributes=[remove_alert_browser_only~loc]}|Pexp_fun(_arg_label,_arg_expression,_fun_pattern,_expr)->letfunction_name=get_function_namepattern.ppat_descinletexpr=last_expr_to_raise_impossible~locfunction_nameexpressioninletvb=Builder.value_binding~loc~pat:pattern~exprin{vbwithpvb_attributes=[remove_alert_browser_only~loc]}|Pexp_ident{txt=longident;loc}->letstringified=Ppxlib.Longident.namelongidentinletmessage=Builder.estring~locstringifiedinletvb=Builder.value_binding~loc~pat:pattern~expr:[%exprRuntime.fail_impossible_action_in_ssr[%emessage]]in{vbwithpvb_attributes=[remove_alert_browser_only~loc]}|_->Builder.value_binding~loc~pat:pattern~expr:(error_only_works_on~loc))letextractor=Ast_pattern.(single_expr_payload__)letexpression_handler~ctxtpayload=letloc=Expansion_context.Extension.extension_point_locctxtinmatch!modewith|Js->payload|Native->(matchpayload.pexp_descwith|Pexp_apply(expression,_)->letstringified=Ppxlib.Pprintast.string_of_expressionexpressioninletmessage=Builder.estring~locstringifiedin[%exprRuntime.fail_impossible_action_in_ssr[%emessage]]|Pexp_constraint({pexp_desc=Pexp_fun(arg_label,_arg_expression,pattern,expression);},type_constraint)->letfn=browser_only_fun~locarg_labelpatternexpressioninBuilder.pexp_constraint~loc{fnwithpexp_attributes=expression.pexp_attributes}type_constraint|Pexp_fun(arg_label,_arg_expression,pattern,expr)->letfunction_name=get_function_namepattern.ppat_descinletnew_fun_pattern=remove_type_constraintpatterninBuilder.pexp_fun~locarg_labelNonenew_fun_pattern(last_expr_to_raise_impossible~locfunction_nameexpr)|Pexp_let(rec_flag,value_bindings,expression)->letpexp_let=Builder.pexp_let~locrec_flag(List.map(funbinding->browser_only_value_bindingbinding.pvb_patbinding.pvb_expr)value_bindings)expressionin[%expr[%epexp_let]]|_->error_only_works_on~loc)letexpression_rule=Context_free.Rule.extension(Extension.V3.declare"browser_only"Extension.Context.expressionextractorexpression_handler)(* Generates a structure_item with a value binding with a pattern and an expression with all the alerts and warnings *)letmake_vb_with_browser_only~loc?type_constraintpatternexpression=matchtype_constraintwith|Sometype_constraint->[%strilet[@warning"-27-32"]([%ppattern]:([%ttype_constraint][@alertbrowser_only"This expression is marked to only run \
on the browser where JavaScript can \
run. You can only use it inside a \
let%browser_only function."]))=([%eexpression][@alert"-browser_only"])]|None->[%strilet[@warning"-27-32"]([%ppattern][@alertbrowser_only"This expression is marked to only run on the browser where \
JavaScript can run. You can only use it inside a \
let%browser_only function."])=([%eexpression][@alert"-browser_only"])]letextractor=letopenAst_patterninletextractor_in_let=pstr_value__(value_binding~pat:__~expr:__^::nil)inpstr@@extractor_in_let^::nilletstructure_item_handler~ctxtrec_flagpatternexpression=letloc=Expansion_context.Extension.extension_point_locctxtinletdo_nothingrec_flag=matchrec_flagwith|Recursive->[%striletrec[%ppattern]=[%eexpression]]|Nonrecursive->[%strilet[%ppattern]=[%eexpression]]inmatch!modewith(* When it's -js, keep item as it is *)|Js->do_nothingrec_flag|Native->(matchexpression.pexp_descwith|Pexp_constraint({pexp_desc=Pexp_fun(arg_label,_arg_expression,fun_pattern,expr);_;},type_constraint)->letoriginal_function_name=get_function_namepattern.ppat_descinletnew_fun_pattern=remove_type_constraintfun_patterninletfn=Builder.pexp_fun~locarg_labelNonenew_fun_pattern(last_expr_to_raise_impossible~locoriginal_function_nameexpr)inletitem={fnwithpexp_attributes=expr.pexp_attributes}inmake_vb_with_browser_only~loc~type_constraintpatternitem|Pexp_fun(arg_label,_arg_expression,fun_pattern,expr)->letoriginal_function_name=get_function_namepattern.ppat_descinletnew_fun_pattern=remove_type_constraintfun_patterninletfn=Builder.pexp_fun~locarg_labelNonenew_fun_pattern(last_expr_to_raise_impossible~locoriginal_function_nameexpr)inletitem={fnwithpexp_attributes=expr.pexp_attributes}inmake_vb_with_browser_only~locpatternitem|Pexp_ident{txt=_longident;loc}->letitem=[%exprObj.magic()]inmake_vb_with_browser_only~locpatternitem|Pexp_newtype(name,expr)->letoriginal_function_name=name.txtinletitem=last_expr_to_raise_impossible~locoriginal_function_nameexprinmake_vb_with_browser_only~locpatternitem|_expr->do_nothingrec_flag)letstructure_item_rule=Context_free.Rule.extension(Extension.V3.declare"browser_only"Extension.Context.structure_itemextractorstructure_item_handler)endlet()=Driver.add_arg"-js"(Unit(fun()->mode:=Js))~doc:"preprocess for js build";Driver.V2.register_transformation"browser_ppx"~rules:[Browser_only.expression_rule;Browser_only.structure_item_rule;Platform.rule;]