123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330(* Yoann Padioleau
*
* Copyright (C) 2010, 2012 Facebook
*
* 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_javaopenEntity_codeopenHighlight_codemoduleAst=Ast_javamoduleV=Visitor_javamoduleT=Parser_javamoduleHC=Highlight_code(*****************************************************************************)(* Prelude *)(*****************************************************************************)(*****************************************************************************)(* Helpers *)(*****************************************************************************)(* we generate fake value here because the real one are computed in a
* later phase in rewrite_categ_using_entities in pfff_visual.
*)letfake_no_def2=NoUseletfake_no_use2=(NoInfoPlace,UniqueDef,MultiUse)(*****************************************************************************)(* Code highlighter *)(*****************************************************************************)(* The idea of the code below is to visit the program either through its
* AST or its list of tokens. The tokens are easier for tagging keywords,
* number and basic entities. The Ast is better for tagging idents
* to figure out what kind of ident it is.
*)letvisit_toplevel~tag_hook_prefs(ast,toks)=letalready_tagged=Hashtbl.create101inlettag=(funiicateg->tag_hookiicateg;Hashtbl.replacealready_taggediitrue)inlettag_ident(id:Ast_java.ident)categ=let(_s,ii)=idintagiicategin(* -------------------------------------------------------------------- *)(* ast phase 1 *)(* tagging the idents of the AST *)letvisitor=V.mk_visitor{V.default_visitorwith(* defs *)V.kdecl=(fun(k,_)d->(matchdwith|Ast.Classx->letident=x.cl_nameintag_identident(Entity(Class,(Def2fake_no_def2)))|Ast.Fieldx->letvar=x.f_varinletident=var.v_nameintag_identident(Entity(Field,(Def2fake_no_def2)))|Ast.Methodx->letvar=x.m_varinletident=var.v_nameintag_identident(Entity(Method,(Def2fake_no_def2)));x.m_formals|>List.iter(funv->letident=v.v_nameintag_identident(ParameterDef))|Ast.Enumx->letident=x.en_nameintag_identident(Entity(Class,(Def2fake_no_def2)))|Ast.Init(_bool,_stmt)->());kd);V.kstmt=(fun(k,_)x->(matchxwith|LocalVarv->letident=v.f_var.v_nameintag_identident(LocalDef)|_->());kx);(* uses *)V.kexpr=(fun(k,_)e->(matchewith|Call(Dot(e,ident),args)->tag_identident(HC.Entity(Method,(Use2fake_no_use2)));ke;List.iterkargs|Dot(e,ident)->tag_identident(Entity(Field,(Use2fake_no_use2)));ke|_->ke););V.ktype=(fun(k,_)e->(matchewith(* done on PRIMITIVE_TYPE below *)|TBasic(_s,_ii)->()|TClassxs->(matchList.revxswith|[]->raiseImpossible|(id,_targs)::xs->tag_identid(Entity(Type,(Use2fake_no_use2)));xs|>List.iter(fun(id,_targs)->tag_identid(Entity(Module,(Use2fake_no_use2)))))|TArray_->());ke);}invisitor(AProgramast);(* -------------------------------------------------------------------- *)(* toks phase 1 *)letrecaux_toksxs=matchxswith|[]->()(* a little bit pad specific *)|T.TComment(ii)::T.TCommentNewline(_ii2)::T.TComment(ii3)::T.TCommentNewline(_ii4)::T.TComment(ii5)::xs->lets=Parse_info.str_of_infoiiinlets5=Parse_info.str_of_infoii5in(match()with|_whens=~".*\\*\\*\\*\\*"&&s5=~".*\\*\\*\\*\\*"->tagiiCommentEstet;tagii5CommentEstet;tagii3CommentSection0|_whens=~".*------"&&s5=~".*------"->tagiiCommentEstet;tagii5CommentEstet;tagii3CommentSection1|_whens=~".*####"&&s5=~".*####"->tagiiCommentEstet;tagii5CommentEstet;tagii3CommentSection2|_->());aux_toksxs(* less: poor's man identifier tagger? *)(* defs *)(* uses *)|_x::xs->aux_toksxsinlettoks'=toks|>Common.exclude(function|T.TCommentSpace_->true|_->false)inaux_tokstoks';(* -------------------------------------------------------------------- *)(* toks phase 2 *)toks|>List.iter(funtok->matchtokwith(* comments *)|T.TCommentii->ifnot(Hashtbl.memalready_taggedii)thentagiiComment|T.TCommentSpaceii->ifnot(Hashtbl.memalready_taggedii)then()else()|T.TCommentNewline_ii->()|T.TUnknownii->tagiiError|T.EOF_ii->()(* values *)|T.TString(_s,ii)->tagiiString|T.TChar(_s,ii)->tagiiString|T.TFloat(_s,ii)|T.TInt(_s,ii)->tagiiNumber|T.TRUE(ii)|T.FALSEii->tagiiBoolean|T.NULLii->tagiiNull|T.PRIMITIVE_TYPE(s,ii)->(matchswith|"void"->tagiiTypeVoid|"boolean"->tagiiTypeInt|_->tagiiTypeInt)|T.OPERATOR_EQ(_s,ii)->tagiiOperator|T.IDENTIFIER(_s,_ii)->()(* keywords *)|T.BOOLEANii->tagiiTypeInt|T.BYTEii|T.CHARii|T.INTii|T.SHORTii|T.LONGii->tagiiTypeInt|T.DOUBLEii|T.FLOATii->tagiiTypeInt|T.VOIDii->tagiiTypeVoid|T.CLASSii|T.ABSTRACTii|T.INTERFACEii|T.PRIVATEii|T.PROTECTEDii|T.PUBLICii|T.THISii|T.SUPERii|T.NEWii|T.INSTANCEOFii|T.EXTENDSii|T.FINALii|T.IMPLEMENTSii->tagiiKeywordObject|T.BREAKii|T.CONTINUEii|T.RETURNii|T.GOTOii->tagiiKeyword|T.TRYii|T.THROWii|T.THROWSii|T.CATCHii|T.FINALLYii->tagiiKeywordExn|T.IFii|T.ELSEii->tagiiKeywordConditional|T.FORii|T.DOii|T.WHILEii->tagiiKeywordLoop|T.SWITCHii|T.CASEii|T.DEFAULTii->tagiiKeywordConditional|T.PACKAGEii|T.IMPORTii->tagiiKeywordModule|T.NATIVEii->tagiiKeyword|T.VOLATILEii|T.STATICii|T.CONSTii->tagiiKeyword|T.SYNCHRONIZEDii->tagiiKeyword|T.STRICTFPii|T.TRANSIENTii|T.ASSERTii->tagiiKeyword(* java ext *)|T.ENUMii->tagiiKeyword|T.ATii->tagiiPunctuation|T.DOTSii->tagiiPunctuation(* symbols *)|T.LPii|T.RPii|T.LCii|T.RCii|T.LBii|T.RBii|T.LB_RBii|T.SMii|T.CMii|T.DOTii|T.EQii|T.LTii|T.LT2ii|T.GTii|T.NOTii|T.COMPLii|T.CONDii|T.COLONii|T.EQ_EQii|T.LEii|T.GEii|T.NOT_EQii|T.ANDii|T.ORii|T.INCRii|T.DECRii|T.PLUSii|T.MINUSii|T.TIMESii|T.DIVii|T.AND_ANDii|T.OR_ORii|T.XORii|T.MODii|T.LSii|T.SRSii|T.URSii->tagiiPunctuation);()