123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390(* Yoann Padioleau
*
* Copyright (C) 2019 r2c
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
* license.txt for more details.
*)openCommonopenAst_jsmoduleG=Ast_generic(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* Ast_js to Ast_generic.
*
* See ast_generic.ml for more information.
*)(*****************************************************************************)(* Helpers *)(*****************************************************************************)letid=funx->xletoption=Common.map_optletlist=List.mapletvreffx=ref(f!x)letbool=idletstring=idleterror=Ast_generic.errorletfake_info()=Parse_info.fake_info"FAKE"(*****************************************************************************)(* Entry point *)(*****************************************************************************)letinfox=xlettokv=infovletwrap=fun_of_a(v1,v2)->letv1=_of_av1andv2=infov2in(v1,v2)letnamev=wrapidvletfilenamev=wrapstringvletlabelv=wrapstringvletqualified_namex=[x,Parse_info.fake_info"TODO qualified name"]letgensym_TODO=-1letresolved_name=function|Local->Some(G.Localgensym_TODO)|Param->Some(G.Paramgensym_TODO)|Globalx->Some(G.Global(qualified_namex))|NotResolved->Nonetypespecial_result=|SR_SpecialofG.special|SR_OtherofG.other_expr_operator|SR_LiteralofG.literal|SR_NeedArgsof(G.exprlist->G.expr)letspecial(x,tok)=matchxwith|UseStrict->SR_OtherG.OE_UseStrict|Null->SR_Literal(G.Nulltok)|Undefined->SR_Literal(G.Undefinedtok)|This->SR_SpecialG.This|Super->SR_SpecialG.Super|Require->SR_OtherG.OE_Require(* TODO: left up to include? *)|Exports->SR_OtherG.OE_Exports|Module->SR_OtherG.OE_Module|Define->SR_OtherG.OE_Define|Arguments->SR_OtherG.OE_Arguments|New->SR_SpecialG.New|NewTarget->SR_OtherG.OE_NewTarget|Eval->SR_SpecialG.Eval|Seq->SR_NeedArgs(funargs->G.Seqargs)|Typeof->SR_SpecialG.Typeof|Instanceof->SR_SpecialG.Instanceof|In->SR_OtherG.OE_In|Delete->SR_OtherG.OE_Delete|Void->SR_Literal(G.Unittok)|Spread->SR_SpecialG.Spread|Yield->SR_NeedArgs(funargs->matchargswith|[e]->G.Yielde|_->errortok"Impossible: Too many arguments to Yield")|YieldStar->SR_OtherG.OE_YieldStar|Await->SR_NeedArgs(funargs->matchargswith|[e]->G.Awaite|_->errortok"Impossible: Too many arguments to Await")|Encapsv1->(matchv1with|None->SR_NeedArgs(funargs->G.Call(G.IdSpecial(G.Concat,fake_info()),args|>List.map(fune->G.Arge)))|Somen->letn=nameninSR_NeedArgs(funargs->G.OtherExpr(G.OE_Encaps,(G.Idn)::(args|>List.map(fune->G.Ee)))))|ArithOpop->SR_Special(G.ArithOpop)|IncrDecrv->SR_Special(G.IncrDecrv)letrecproperty_name=function|PNv1->letv1=namev1inLeftv1|PN_Computedv1->letv1=exprv1inRightv1andexpr(x:expr)=matchxwith|Boolv1->letv1=wrapboolv1inG.L(G.Boolv1)|Numv1->letv1=wrapstringv1inG.L(G.Floatv1)|Stringv1->letv1=wrapstringv1inG.L(G.Stringv1)|Regexpv1->letv1=wrapstringv1inG.L(G.Regexpv1)|Id(v1,refresolved)->letv1=namev1inletv2=G.empty_name_infoinletv3={(G.empty_id_info())withG.id_resolved=vrefresolved_namerefresolved}inG.Name((v1,v2),v3)|IdSpecial(v1)->letx=specialv1in(matchxwith|SR_Specialv->G.IdSpecial(v,sndv1)|SR_NeedArgs_->error(sndv1)"Impossible: should have been matched in Call first"|SR_Literall->G.Ll|SR_Otherx->G.OtherExpr(x,[]))|Nop->G.Nop|Assign((v1,v2))->letv1=exprv1andv2=exprv2inG.Assign(v1,v2)|ArrAccess((v1,v2))->letv1=exprv1andv2=exprv2inG.ArrayAccess(v1,v2)|Objv1->letflds=obj_v1inG.Recordflds|Ellipsesv1->letv1=infov1inG.Ellipsesv1|Class(v1,_v2TODO)->letdef,_more_attrsTODOEMPTY=class_v1inG.AnonClassdef|ObjAccess((v1,v2))->letv1=exprv1inletv2=property_namev2in(matchv2with|Leftn->G.ObjAccess(v1,n)|Righte->G.OtherExpr(G.OE_ObjAccess_PN_Computed,[G.Ev1;G.Ee]))|Fun((v1,_v2TODO))->letdef,_more_attrs=fun_v1in(* todo? assert more_attrs = []? *)G.Lambda(def)|Apply((IdSpecialv1,v2))->letx=specialv1inletv2=listexprv2in(matchxwith|SR_Specialv->G.Call(G.IdSpecial(v,sndv1),v2|>List.map(fune->G.Arge))|SR_Literal_->error(sndv1)"Weird: literal in call position"|SR_Otherx->(* ex: NewTarget *)G.Call(G.OtherExpr(x,[]),v2|>List.map(fune->G.Arge))|SR_NeedArgsf->fv2)|Apply((v1,v2))->letv1=exprv1andv2=listexprv2inG.Call(v1,v2|>List.map(fune->G.Arge))|Arr((v1))->letv1=listexprv1inG.Container(G.Array,v1)|Conditional((v1,v2,v3))->letv1=exprv1andv2=exprv2andv3=exprv3inG.Conditional(v1,v2,v3)andstmtx=matchxwith|VarDeclv1->letv1=def_of_varv1inG.DefStmt(v1)|Blockv1->letv1=liststmtv1inG.Blockv1|ExprStmtv1->letv1=exprv1inG.ExprStmtv1|If((v1,v2,v3))->letv1=exprv1andv2=stmtv2andv3=stmtv3inG.If(v1,v2,v3)|Do((v1,v2))->letv1=stmtv1andv2=exprv2inG.DoWhile(v1,v2)|While((v1,v2))->letv1=exprv1andv2=stmtv2inG.While(v1,v2)|For((v1,v2))->letv1=for_headerv1andv2=stmtv2inG.For(v1,v2)|Switch((v1,v2))->letv1=exprv1andv2=listcasev2inG.Switch(v1,v2)|Continuev1->letv1=optionlabelv1inG.Continue(v1|>option(funn->G.Name((n,G.empty_name_info),G.empty_id_info())))|Breakv1->letv1=optionlabelv1inG.Break(v1|>option(funn->G.Name((n,G.empty_name_info),G.empty_id_info())))|Returnv1->letv1=exprv1inG.Returnv1|Label((v1,v2))->letv1=labelv1andv2=stmtv2inG.Label(v1,v2)|Throwv1->letv1=exprv1inG.Throwv1|Try((v1,v2,v3))->letv1=stmtv1andv2=option(fun(v1,v2)->letv1=namev1andv2=stmtv2inG.PatVar(v1,G.empty_id_info()),v2)v2andv3=optionstmtv3inG.Try(v1,Common.opt_to_listv2,v3)andfor_header=function|ForClassic((v1,v2,v3))->letv2=exprv2inletv3=exprv3in(matchv1with|Leftvars->letvars=vars|>List.map(funx->let(a,b)=var_of_varxinG.ForInitVar(a,b))inG.ForClassic(vars,v2,v3)|Righte->lete=expreinG.ForClassic([G.ForInitExpre],v2,v3))|ForIn((v1,v2))->letv2=exprv2inletpattern=matchv1with|Leftv->letv=def_of_varvinG.OtherPat(G.OP_Var,[G.Defv])|Righte->lete=expreinG.OtherPat(G.OP_Expr,[G.Ee])inG.ForEach(pattern,v2)andcase=function|Case((v1,v2))->letv1=exprv1andv2=stmtv2in[G.Casev1],v2|Defaultv1->letv1=stmtv1in[G.Default],v1anddef_of_var{v_name=x_name;v_kind=x_kind;v_init=x_init;v_resolved=x_resolved}=letv1=namex_nameinletv2=var_kindx_kindinletent=G.basic_entityv1[v2]in(matchx_initwith|Fun(v3,_nTODO)->letdef,more_attrs=fun_v3in{entwithG.attrs=ent.G.attrs@more_attrs},G.FuncDefdef|Class(v3,_nTODO)->letdef,more_attrs=class_v3in{entwithG.attrs=ent.G.attrs@more_attrs},G.ClassDefdef|_->letv3=exprx_initinlet_v4TODO=vrefresolved_namex_resolvedinent,G.VarDef{G.vinit=Somev3;G.vtype=None})andvar_of_var{v_name=x_name;v_kind=x_kind;v_init=x_init;v_resolved=x_resolved}=letv1=namex_nameinletv2=var_kindx_kindinletent=G.basic_entityv1[v2]inletv3=exprx_initinlet_v4TODO=vrefresolved_namex_resolvedinent,{G.vinit=Somev3;G.vtype=None}andvar_kind=function|Var->G.Var|Let->G.Let|Const->G.Constandfun_{f_props=f_props;f_params=f_params;f_body=f_body}=letv1=listfun_propf_propsinletv2=listparameterf_paramsinletv3=stmtf_bodyin{G.fparams=v2;frettype=None;fbody=v3;},v1andparameterx=matchxwith{p_name=p_name;p_default=p_default;p_dots=p_dots}->letv1=namep_nameinletv2=optionexprp_defaultinletv3=boolp_dotsinG.ParamClassic{G.pname=v1;pdefault=v2;ptype=None;pattrs=ifv3then[G.Variadic]else[];pinfo=G.empty_id_info();}andfun_prop=function|Get->G.Getter|Set->G.Setter|Generator->G.Generator|Async->G.Asyncandobj_v=listpropertyvandclass_{c_extends=c_extends;c_body=c_body}=letv1=optionexprc_extendsinletv2=listpropertyc_bodyin(* todo: could analyze arg to look for Id *)letextends=matchv1with|None->[]|Somee->[G.OtherType(G.OT_Expr,[G.Ee])]in{G.ckind=G.Class;cextends=extends;cimplements=[];cbody=v2;},[]andpropertyx=matchxwith|Field((v1,v2,v3))->letv1=property_namev1andv2=listproperty_propv2andv3=exprv3in(matchv1with|Leftn->letent=G.basic_entitynv2in(* todo: could be a Lambda in which case we should return a FuncDef? *)G.FieldVar(ent,{G.vinit=Somev3;vtype=None})|Righte->G.FieldDynamic(e,v2,v3))|FieldSpreadv1->letv1=exprv1inG.FieldSpreadv1andproperty_prop=function|Static->G.Static|Public->G.Public|Private->G.Private|Protected->G.Protectedletrectoplevelx=matchxwith|Vv1->letv1=def_of_varv1inG.IDefv1|S((v1,v2))->let_v1TODO=tokv1andv2=stmtv2inG.IStmtv2|Mv1->letv1=module_directivev1inG.IDirv1andmodule_directivex=matchxwith|Import((v1,v2,v3))->letv1=namev1andv2=namev2andv3=filenamev3inG.ImportFrom(G.FileNamev3,[v1,Somev2])|ModuleAlias((v1,v2))->letv1=namev1andv2=filenamev2inG.ImportAs(G.FileNamev2,Somev1)|ImportCss((v1))->letv1=namev1inG.OtherDirective(G.OI_ImportCss,[G.Idv1])|ImportEffect((v1))->letv1=namev1inG.OtherDirective(G.OI_ImportEffect,[G.Idv1])|Export((v1))->letv1=namev1inG.OtherDirective(G.OI_Export,[G.Idv1])andprogramv=listtoplevelvletany=function|Exprv1->letv1=exprv1inG.Ev1|Stmtv1->letv1=stmtv1inG.Sv1|Topv1->letv1=toplevelv1inG.Iv1|Programv1->letv1=programv1inG.Prv1