123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2019 The MOPSA Project. *)(* *)(* This program is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License as published *)(* by the Free Software Foundation, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program 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 *)(* GNU Lesser General Public License for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Pretty printer of the Python extension to the AST. *)openMopsaopenAstopenFormatletpp_vars=Format.pp_print_list~pp_sep:(funfmt()->Format.fprintffmt", ")pp_varletpp_exceptfmte=fprintffmt"except %a%a:@\n@[<h 2> %a@]"(funfmte->matchewith|None->()|Somee->pp_exprfmte)e.py_excpt_type(funfmtv->matchvwith|None->()|Somev->fprintffmt" as %a"pp_varv)e.py_excpt_namepp_stmte.py_excpt_bodyletpp_py_objectfmt(obj:py_object)=matchobjwith|(addr,None)->fprintffmt"⟪%a⟫"pp_addraddr|(addr,Somee)->fprintffmt"⟪%a :: %a⟫"pp_addraddrpp_exprelet()=register_program_pp(fundefaultfmtprog->matchprog.prog_kindwith|Py_program(_,_,body)->pp_stmtfmtbody|_->defaultfmtprog);register_typ_pp(fundefaultfmttyp->matchtypwith|T_pyNone->pp_print_stringfmt"py"|T_py(SomeBool)->pp_print_stringfmt"py-bool"|T_py(SomeNotImplemented)->pp_print_stringfmt"py-notimplemented"|T_py(SomeNoneType)->pp_print_stringfmt"py-none"|T_py(SomeComplex)->pp_print_stringfmt"py-complex"|T_py(SomeBytes)->pp_print_stringfmt"py-bytes"|T_py(SomeStr)->pp_print_stringfmt"py-str"|T_py(Some(Float_))->pp_print_stringfmt"py-float"|T_py(SomeInt)->pp_print_stringfmt"py-int"|_->defaultfmttyp);register_constant_pp(fundefaultfmt->function|C_py_ellipsis->pp_print_stringfmt"C_py_ellipsis"|C_py_none->pp_print_stringfmt"C_py_None"|C_py_not_implemented->pp_print_stringfmt"NotImplemented"|C_py_imagj->fprintffmt"%aj"pp_print_floatj|c->defaultfmtc);register_operator_pp(fundefaultfmt->function|O_py_and->pp_print_stringfmt"and"|O_py_or->pp_print_stringfmt"or"|O_py_floor_div->pp_print_stringfmt"//"|O_py_is->pp_print_stringfmt"is"|O_py_is_not->pp_print_stringfmt"is not"|O_py_in->pp_print_stringfmt"in"|O_py_not_in->pp_print_stringfmt"not in"|O_py_mat_mult->pp_print_stringfmt"@"|O_py_not->pp_print_stringfmt"py_not"|op->defaultfmtop);register_expr_pp(fundefaultfmtexp->matchekindexpwith|E_py_ll_hasattr(e,attr)->Format.fprintffmt"E_py_ll_hasattr(%a, %a)"pp_exprepp_exprattr|E_py_ll_getattr(e,attr)->Format.fprintffmt"E_py_ll_getattr(%a, %a)"pp_exprepp_exprattr|E_py_ll_setattr(e,attr,ovalu)->Format.fprintffmt"E_py_ll_setattr(%a, %a, %a)"pp_exprepp_exprattr(OptionExt.printpp_expr)ovalu|E_py_annote->fprintffmt"(annot) %a"pp_expre|E_py_undefinedtrue->fprintffmt"global undef"|E_py_undefinedfalse->fprintffmt"local undef"|E_py_objectobj->pp_py_objectfmtobj|E_py_attribute(obj,attr)->fprintffmt"%a.%s"pp_exprobjattr|E_py_list(elts)->fprintffmt"[%a]"(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_expr)elts|E_py_tuple(elts)->ifList.lengthelts=1thenfprintffmt"(%a,)"pp_expr(List.hdelts)elsefprintffmt"(%a)"(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_expr)elts|E_py_set(elts)->fprintffmt"{%a}"(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_expr)elts|E_py_dict(keys,values)->fprintffmt"{%a}"(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")(funfmt(k,v)->fprintffmt"%a: %a"pp_exprkpp_exprv))(List.combinekeysvalues)|E_py_index_subscript(obj,index)->fprintffmt"%a[%a]"pp_exprobjpp_exprindex|E_py_slice_subscript(obj,a,b,s)->fprintffmt"%a[%a : %a : %a]"pp_exprobjpp_exprapp_exprbpp_exprs|E_py_call(f,args,keywords)->fprintffmt"%a(%a%a%a)"pp_exprf(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_expr)args(funfmt->function[]->()|_->pp_print_stringfmt", ")keywords(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")(funfmt->function|(None,kwd)->fprintffmt"**%a"pp_exprkwd|(Somek,v)->fprintffmt"%s = %a"kpp_exprv))keywords|E_py_yield(e)->fprintffmt"yield %a"pp_expre|E_py_yield_from(e)->fprintffmt"yield from %a"pp_expre|E_py_if(test,body,orelse)->fprintffmt"%a if %a else %a"pp_exprbodypp_exprtestpp_exprorelse|E_py_list_comprehension(e,comprhs)->fprintffmt"[%a %a]"pp_expre(pp_print_list~pp_sep:(funfmt()->pp_print_stringfmt" ")(funfmt(target,iter,conds)->fprintffmt"for %a in %a%a"pp_exprtargetpp_expriter(pp_print_list(funfmtcond->fprintffmt" if %a"pp_exprcond))conds))comprhs|E_py_set_comprehension(e,comprhs)->fprintffmt"{%a %a}"pp_expre(pp_print_list~pp_sep:(funfmt()->pp_print_stringfmt" ")(funfmt(target,iter,conds)->fprintffmt"for %a in %a%a"pp_exprtargetpp_expriter(pp_print_list(funfmtcond->fprintffmt" if %a"pp_exprcond))conds))comprhs|E_py_generator_comprehension(e,comprhs)->fprintffmt"(%a %a)"pp_expre(pp_print_list~pp_sep:(funfmt()->pp_print_stringfmt" ")(funfmt(target,iter,conds)->fprintffmt"for %a in %a%a"pp_exprtargetpp_expriter(pp_print_list(funfmtcond->fprintffmt" if %a"pp_exprcond))conds))comprhs|E_py_dict_comprehension(k,v,comprhs)->fprintffmt"{%a: %a %a}"pp_exprkpp_exprv(pp_print_list~pp_sep:(funfmt()->pp_print_stringfmt" ")(funfmt(target,iter,conds)->fprintffmt"for %a in %a%a"pp_exprtargetpp_expriter(pp_print_list(funfmtcond->fprintffmt" if %a"pp_exprcond))conds))comprhs|E_py_lambdal->fprintffmt"lambda %a: %a"(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_var)l.py_lambda_parameterspp_exprl.py_lambda_body|E_py_multi_compare(left,ops,rights)->letl=List.combineopsrightsinfprintffmt"%a %a"pp_exprleft(pp_print_list~pp_sep:(funfmt()->fprintffmt" ")(funfmt(op,right)->fprintffmt"%a %a"pp_operatoroppp_exprright))l|E_py_bytes(s)->fprintffmt"b\"%s\""s|E_py_check_annot(e1,e2)->fprintffmt"check_annot(%a: %a)"pp_expre1pp_expre2|_->defaultfmtexp);register_stmt_pp(fundefaultfmtstmt->matchskindstmtwith|S_py_class(cls)->fprintffmt"class %a(%a):@\n@[<h 2> %a@]"pp_varcls.py_cls_var(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_expr)cls.py_cls_basespp_stmtcls.py_cls_body|S_py_function(func)->fprintffmt"%a@\ndef %a(%a%a%s%a%a)%a:@\n@[<h 2> %a@]"(pp_print_list~pp_sep:(funfmt()->fprintffmt"@\n")(funfmtd->fprintffmt"@@%a"pp_exprd))func.py_func_decorspp_varfunc.py_func_var(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")(funfmt(var,oty)->matchotywith|None->pp_varfmtvar|Somety->fprintffmt"%a: %a"pp_varvarpp_exprty))(List.map2(funxy->(x,y))func.py_func_parametersfunc.py_func_types_in)(OptionExt.print~none:""~some:", *"pp_var)func.py_func_vararg(matchfunc.py_func_varargwith|None->""|_->", ")(pp_print_list~pp_sep:(funfmt()->fprintffmt", ")pp_var)func.py_func_kwonly_args(OptionExt.print~none:""~some:", **"pp_var)func.py_func_kwarg(funfmtoty->matchotywith|None->()|Somety->fprintffmt" -> %a"pp_exprty)func.py_func_type_outpp_stmtfunc.py_func_body|S_py_try(body,excepts,orelse,final)->fprintffmt"try:@\n@[<h 2> %a@]@\n%a@\nelse:@[<h 2> %a@]@\nfinally:@[<h 2> %a@]"pp_stmtbody(pp_print_list~pp_sep:(funfmt()->fprintffmt"@\n")pp_except)exceptspp_stmtorelsepp_stmtfinal|S_py_raisee->fprintffmt"raise %a"(funfmt->functionNone->()|Somee->pp_exprfmte)e|S_py_while(test,body,orelse)->fprintffmt"while %a:@\n@[<h 2> %a@]@\nelse:@\n@[<h 2> %a@]"pp_exprtestpp_stmtbodypp_stmtorelse|S_py_if(test,sthen,selse)->fprintffmt"@[<v 4>if (%a) {@,%a@]@,@[<v 4>} else {@,%a@]@,}"pp_exprtestpp_stmtsthenpp_stmtselse|S_py_multi_assign(targets,e)->fprintffmt"%a %a"(pp_print_list~pp_sep:(funfmt()->fprintffmt" ")(funfmtx->fprintffmt"%a ="pp_exprx))targetspp_expre|S_py_aug_assign(x,op,e)->fprintffmt"%a %a= %a"pp_exprxpp_operatoroppp_expre|S_py_annot(x,typ)->fprintffmt"%a: %a"pp_exprxpp_exprtyp|S_py_check_annot(x,typ)->fprintffmt"S_check_annot %a: %a"pp_exprxpp_exprtyp|S_py_for(target,iter,body,orelse)->fprintffmt"for %a in %a:@\n@[<h 2> %a@]@\nelse:@\n@[<h 2> %a@]"pp_exprtargetpp_expriterpp_stmtbodypp_stmtorelse|S_py_import(mdl,asname,vroot)->fprintffmt"import %s%a"mdl(funfmt->functionNone->()|Somename->fprintffmt" as %a"pp_varname)asname|S_py_import_from(mdl,name,vroot,asname)->fprintffmt"from %s import %s as %a"mdlnamepp_varasname|S_py_deletee->fprintffmt"del %a"pp_expre|S_py_assert(e,None)->fprintffmt"assert %a"pp_expre|S_py_assert(e,Somemsg)->fprintffmt"assert %a, %a"pp_exprepp_exprmsg|S_py_with(ctx,asname,body)->fprintffmt"with %a%a:@\n@[<h 2> %a@]"pp_exprctx(funfmt->functionNone->()|Somename->fprintffmt" as %a"pp_exprname)asnamepp_stmtbody|_->defaultfmtstmt);()