123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535(* 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_javamoduleG=Ast_generic(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* Ast_java to Ast_generic.
*
* See ast_generic.ml for more information.
*)(*****************************************************************************)(* Helpers *)(*****************************************************************************)letid=funx->xletoption=Common.map_optletlist=List.mapletstring=idletbool=idletint=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)letlist1_of_a=list_of_aletidentv=wrapstringvletqualified_identv=listidentvletrectyp=function|TBasicv1->letv1=wrapstringv1inG.TyBuiltinv1|TClassv1->letv1=class_typev1inv1|TArrayv1->letv1=typv1inG.TyArray(None,v1)andclass_typev=letres=list1(fun(v1,v2)->letv1=identv1and_v2TODO=listtype_argumentv2in(v1))vin(matchList.revreswith|[]->raiseImpossible(* list1 *)|name::xs->letinfo={G.name_typeargs=None;(* could be v1TODO above *)name_qualifier=Some(List.revxs);}inG.TyApply((name,info),[]))andtype_argument=function|TArgumentv1->letv1=ref_typev1inG.TypeArgv1|TQuestionv1->letv1=option(fun(v1,v2)->letv1=boolv1andv2=ref_typev2in(v1,v2))v1inletanys=matchv1with|None->[]|Some(_boolTODO,t)->[G.Tt]inG.OtherTypeArg(G.OTA_Question,anys)andref_typev=typvlettype_parameter=function|TParam((v1,v2))->letv1=identv1andv2=listref_typev2inv1,(v2|>List.map(funt->G.Extendst))letrecmodifier=function|Public->G.Public|Protected->G.Protected|Private->G.Private|Abstract->G.Abstract|Static->G.Static|Final->G.Final|StrictFP->G.OtherAttribute(G.OA_StrictFP,[])|Transient->G.OtherAttribute(G.OA_Transient,[])|Volatile->G.Volatile|Synchronized->G.OtherAttribute(G.OA_Synchronized,[])|Native->G.OtherAttribute(G.OA_Native,[])|Annotation_v1->(* let _v1TODO = annotation v1 in *)G.OtherAttribute(G.OA_AnnotJavaOther,[])andmodifiersv=list(wrapmodifier)v|>List.mapfst(*
and annotation (v1, v2) =
let _v1 = name_or_class_type v1
and _v2 = option annotation_element v2
in ()
()
and annotation_element =
function
| AnnotArgValue v1 -> let _v1 = element_value v1 in ()
| AnnotArgPairInit v1 -> let _v1 = list annotation_pair v1 in ()
| EmptyAnnotArg -> ()
and element_value =
function
| AnnotExprInit v1 -> let _v1 = expr v1 in ()
| AnnotNestedAnnot v1 -> let _v1 = annotation v1 in ()
| AnnotArrayInit v1 -> let _v1 = list element_value v1 in ()
and annotation_pair (v1, v2) =
let _v1 = ident v1 and _v2 = element_value v2 in ()
and name_or_class_type v = list identifier_ v
and identifier_ =
function
| Id v1 -> let _v1 = ident v1 in ()
| Id_then_TypeArgs ((v1, v2)) ->
let _v1 = ident v1 and _v2 = list type_argument v2 in ()
| TypeArgs_then_Id ((v1, v2)) ->
let _v1 = list type_argument v1 and _v2 = identifier_ v2 in ()
*)andnamev=letres=list1(fun(v1,v2)->let_v1TODO=listtype_argumentv1andv2=identv2in(v2))vin(matchList.revreswith|[]->raiseImpossible(* list1 *)|name::xs->letinfo={G.name_typeargs=None;(* could be v1TODO above *)name_qualifier=Some(List.revxs);}in(name,info))andliteral=function|Intv1->letv1=wrapstringv1in(G.Intv1)|Floatv1->letv1=wrapstringv1in(G.Floatv1)|Stringv1->letv1=wrapstringv1in(G.Stringv1)|Charv1->letv1=wrapstringv1in(G.Charv1)|Nullv1->letv1=tokv1in(G.Nullv1)|Boolv1->letv1=wrapboolv1in(G.Boolv1)andexpre=matchewith|Ellipsesv1->letv1=tokv1inG.Ellipsesv1|Namev1->let(a,b)=namev1inG.Name((a,b),G.empty_id_info())|NameOrClassType_v1->letii=Lib_parsing_java.ii_of_any(AExpre)inerror(List.hdii)"NameOrClassType should only appear in (ignored) annotations"|Literalv1->letv1=literalv1inG.Lv1|ClassLiteralv1->letv1=typv1inG.OtherExpr(G.OE_ClassLiteral,[G.Tv1])|NewClass((v1,v2,v3))->letv1=typv1andv2=argumentsv2andv3=optiondeclsv3in(matchv3with|None->G.Call(G.IdSpecial(G.New,fake_info()),(G.ArgTypev1)::v2)|Somedecls->letanonclass=G.AnonClass{G.ckind=G.Class;cextends=[v1];cimplements=[];cbody=List.mapG.stmt_to_fielddecls}inG.Call(G.IdSpecial(G.New,fake_info()),(G.Arganonclass)::v2))|NewArray((v1,v2,v3,v4))->letv1=typv1andv2=argumentsv2andv3=intv3andv4=optioninitv4inletrecmk_arrayn=ifn<1thenraiseImpossible;(* see parser_java.mly dims rule *)ifn=1thenG.TyArray(None,v1)elseG.TyArray(None,mk_array(n-1))inlett=mk_arrayv3in(matchv4with|None->G.Call(G.IdSpecial(G.New,fake_info()),(G.ArgTypet)::v2)|Some_decls->letii=Lib_parsing_java.ii_of_any(AExpre)inerror(List.hdii)"TODO: NewArray with initializer not handled yet")(* x.new Y(...) {...} *)|NewQualifiedClass((v1,v2,v3,v4))->letv1=exprv1andv2=identv2andv3=argumentsv3andv4=optiondeclsv4inletany=[G.Ev1;G.Idv2]@(v3|>List.map(funarg->G.Ararg))@(Common.opt_to_listv4|>List.flatten|>List.map(funst->G.Sst))inG.OtherExpr(G.OE_NewQualifiedClass,any)|Call((v1,v2))->letv1=exprv1andv2=argumentsv2inG.Call(v1,v2)|Dot((v1,v2))->letv1=exprv1andv2=identv2inG.ObjAccess(v1,v2)|ArrayAccess((v1,v2))->letv1=exprv1andv2=exprv2inG.ArrayAccess(v1,v2)|Postfix((v1,(v2,tok)))->letv1=exprv1andv2=fix_opv2inG.Call(G.IdSpecial(G.IncrDecr(v2,G.Postfix),tok),[G.Argv1])|Prefix(((v1,tok),v2))->letv1=fix_opv1andv2=exprv2inG.Call(G.IdSpecial(G.IncrDecr(v1,G.Prefix),tok),[G.Argv2])|Unary((v1,v2))->let(v1,tok)=v1andv2=exprv2inG.Call(G.IdSpecial(G.ArithOpv1,tok),[G.Argv2])|Infix((v1,(v2,tok),v3))->letv1=exprv1andv2=v2andv3=exprv3inG.Call(G.IdSpecial(G.ArithOp(v2),tok),[G.Argv1;G.Argv3])|Cast((v1,v2))->letv1=typv1andv2=exprv2inG.Cast(v1,v2)|InstanceOf((v1,v2))->letv1=exprv1andv2=ref_typev2inG.Call(G.IdSpecial(G.Instanceof,fake_info()),[G.Argv1;G.ArgTypev2])|Conditional((v1,v2,v3))->letv1=exprv1andv2=exprv2andv3=exprv3inG.Conditional(v1,v2,v3)|Assign((v1,v2))->letv1=exprv1andv2=exprv2inG.Assign(v1,v2)|AssignOp((v1,(v2,tok),v3))->letv1=exprv1andv3=exprv3inG.AssignOp(v1,(v2,tok),v3)andargumentsv=listexprv|>List.map(fune->G.Arge)andfix_opv=vandstmt=function|Empty->G.Block[]|Blockv1->letv1=stmtsv1inG.Blockv1|Exprv1->letv1=exprv1inG.ExprStmtv1|If((v1,v2,v3))->letv1=exprv1andv2=stmtv2andv3=stmtv3inG.If(v1,v2,v3)|Switch((v1,v2))->letv1=exprv1andv2=list(fun(v1,v2)->letv1=casesv1andv2=stmtsv2inv1,G.stmt1v2)v2inG.Switch(v1,v2)|While((v1,v2))->letv1=exprv1andv2=stmtv2inG.While(v1,v2)|Do((v1,v2))->letv1=stmtv1andv2=exprv2inG.DoWhile(v1,v2)|For((v1,v2))->letv1=for_controlv1andv2=stmtv2inG.For(v1,v2)|Breakv1->letv1=optionident_labelv1inG.Breakv1|Continuev1->letv1=optionident_labelv1inG.Continuev1|Returnv1->letv1=optionexprv1inG.Return(G.opt_to_nopv1)|Label((v1,v2))->letv1=identv1andv2=stmtv2inG.Label(v1,v2)|Sync((v1,v2))->letv1=exprv1andv2=stmtv2inG.OtherStmt(G.OS_Sync,[G.Ev1;G.Sv2])|Try((v1,v2,v3))->letv1=stmtv1andv2=catchesv2andv3=optionstmtv3inG.Try(v1,v2,v3)|Throwv1->letv1=exprv1inG.Throwv1|LocalVarv1->let(ent,v)=var_with_initv1inG.DefStmt(ent,G.VarDefv)|LocalClassv1->let(ent,cdef)=class_declv1inG.DefStmt(ent,G.ClassDefcdef)|Assert((v1,v2))->letv1=exprv1andv2=optionexprv2inG.Assert(v1,v2)andident_labelx=letx=identxinG.Name((x,G.empty_name_info),G.empty_id_info())andstmtsv=liststmtvandcase=function|Casev1->letv1=exprv1inG.Casev1|Default->G.Defaultandcasesv=listcasevandfor_control=function|ForClassic((v1,v2,v3))->letv1=for_initv1andv2=listexprv2andv3=listexprv3inG.ForClassic(v1,G.Seqv2,G.Seqv3)|Foreach((v1,v2))->letent=varv1andv2=exprv2inletpat=G.OtherPat(G.OP_Var,[G.Enent])inG.ForEach(pat,v2)andfor_init=function|ForInitVarsv1->letv1=listvar_with_initv1inv1|>List.map(fun(ent,v)->G.ForInitVar(ent,v))|ForInitExprsv1->letv1=listexprv1inv1|>List.map(fune->G.ForInitExpre)andvar{v_name=name;v_mods=mods;v_type=xtyp}=letv1=identnameinletv2=modifiersmodsinletv3=typxtypin{G.name=v1;G.attrs=v2;G.type_=Somev3;tparams=[];info=G.empty_id_info();}andcatch(v1,v2)=let(ent:G.entity)=varv1andv2=stmtv2inletpat=G.OtherPat(G.OP_Var,[G.Enent])inpat,v2andcatchesv=listcatchvandvarsv=listvarvandvar_with_init{f_var=f_var;f_init=f_init}=letent=varf_varinletinit=optioninitf_initinent,{G.vinit=init;vtype=None}andinit=function|ExprInitv1->letv1=exprv1inv1|ArrayInitv1->letv1=listinitv1inG.Container(G.Array,v1)andparamsv=letv=varsvinv|>List.map(funent->G.ParamClassic(G.entity_to_parament))andmethod_decl{m_var=m_var;m_formals=m_formals;m_throws=m_throws;m_body=m_body}=letv1=varm_varinletrett=matchv1.G.type_withNone->raiseImpossible|Somex->xinletv2=paramsm_formalsinletv3=listqualified_identm_throwsinletv4=stmtm_bodyinletthrows=v3|>List.map(funqu_id->G.OtherAttribute(G.OA_AnnotThrow,[G.Diqu_id]))in{v1withG.attrs=v1.G.attrs@throws},{G.fparams=v2;frettype=Somerett;fbody=v4}andfieldv=var_with_initvandenum_decl{en_name=en_name;en_mods=en_mods;en_impls=en_impls;en_body=en_body}=letv1=identen_nameinletv2=modifiersen_modsinlet_v3TODO=listref_typeen_implsinlet(v4,v5)=en_bodyinletv4=listenum_constantv4inlet_v5TODO=declsv5inletent=G.basic_entityv1v2inlettdef={G.tbody=G.OrTypev4}inent,tdefandenum_constant=function|EnumSimplev1->letv1=identv1inG.OrConstructor(v1,[])|EnumConstructor((v1,v2))->letv1=identv1and_v2TODO=argumentsv2inG.OrConstructor(v1,[])|EnumWithMethods((v1,v2))->letv1=identv1and_v2TODO=listmethod_declv2inG.OrConstructor(v1,[])andclass_decl{cl_name=cl_name;cl_kind=cl_kind;cl_tparams=cl_tparams;cl_mods=cl_mods;cl_extends=cl_extends;cl_impls=cl_impls;cl_body=cl_body}=letv1=identcl_nameinletv2=class_kindcl_kindinletv3=listtype_parametercl_tparamsinletv4=modifierscl_modsinletv5=optiontypcl_extendsinletv6=listref_typecl_implsinletv7=declscl_bodyinletfields=List.mapG.stmt_to_fieldv7inletent={(G.basic_entityv1v4)withG.tparams=v3}inletcdef={G.ckind=v2;cextends=Common.opt_to_listv5;cimplements=v6;cbody=fields;}inent,cdefandclass_kind=function|ClassRegular->G.Class|Interface->G.Interfaceanddecldecl=matchdeclwith|Classv1->let(ent,def)=class_declv1inG.DefStmt(ent,G.ClassDefdef)|Methodv1->let(ent,def)=method_declv1inG.DefStmt(ent,G.FuncDefdef)|Fieldv1->let(ent,def)=fieldv1inG.DefStmt(ent,G.VarDefdef)|Enumv1->let(ent,def)=enum_declv1inG.DefStmt(ent,G.TypeDefdef)|Init((v1,v2))->let_v1TODO=boolv1andv2=stmtv2inv2anddeclsv=listdeclvletcompilation_unit{package=package;imports=imports;decls=xdecls}=letv1=optionqualified_identpackageinletv2=list(fun(v1,v2)->let_v1TODO=boolv1andv2=qualified_identv2inmatchList.revv2with|("*",_)::xs->G.ImportAs(G.DottedName(List.revxs),None)|[]->raiseImpossible|x::xs->G.ImportFrom(G.DottedName(List.revxs),[(x,None)]))importsinletv3=declsxdeclsinletitems=v3|>List.mapG.stmt_to_iteminletimports=v2|>List.map(funimport->G.IDirimport)in(matchv1with|None->items@imports|Some[]->raiseImpossible|Somexs->letid=Common2.list_lastxsinletent=G.basic_entityid[]in[G.IDef(ent,G.ModuleDef{G.mbody=G.ModuleStruct(None,items@imports)})])letprogramv=compilation_unitvletany=function|AIdentv1->letv1=identv1inG.Idv1|AExprv1->letv1=exprv1inG.Ev1|AStmtv1->letv1=stmtv1inG.Sv1|ATypv1->letv1=typv1inG.Tv1|AVarv1->letv1=varv1inG.Env1|AInitv1->letv1=initv1inG.Ev1|AMethodv1->let(ent,def)=method_declv1inG.Def(ent,G.FuncDefdef)|AFieldv1->let(ent,def)=fieldv1inG.Def(ent,G.VarDefdef)|AClassv1->let(ent,def)=class_declv1inG.Def(ent,G.ClassDefdef)|ADeclv1->letv1=declv1inG.Sv1|AProgramv1->letv1=programv1inG.Prv1