Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file highlight_js.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289(* Yoann Padioleau
*
* Copyright (C) 2010 Facebook
* Copyright (C) 2019 Yoann Padioleau
*
* 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.
*)openCommonopenHighlight_codeopenAst_jsmoduleT=Parser_jsmoduleE=Entity_codemoduleH=Highlight_code(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* Syntax highlighting for Javascript code for codemap (and now also efuns).
*)(*****************************************************************************)(* Helpers when have global-analysis information *)(*****************************************************************************)letfake_no_def2=NoUseletfake_no_use2=(NoInfoPlace,UniqueDef,MultiUse)(*****************************************************************************)(* Code highlighter *)(*****************************************************************************)letvisit_program~tag_hook_prefs(cst,toks)=letalready_tagged=Hashtbl.create101inlettag=(funiicateg->(matchcategwith(* Javascript allows to use keywords as identifiers for flds/methods/...*)|Keyword|KeywordExn|KeywordLoop|KeywordModulewhenHashtbl.memalready_taggedii->()|_->tag_hookiicateg;);Hashtbl.addalready_taggediitrue)inlettag_name(_s,ii)categ=(* so treat the most specific in the enclosing code and then
* do not fear to write very general case patterns later because
* the specific will have priority over the general
* (e.g., a Method use vs a Field use)
*)ifnot(Hashtbl.memalready_taggedii)thentagiicateginlettag_if_not_taggediicateg=ifnot(Hashtbl.memalready_taggedii)thentagiicategin(* -------------------------------------------------------------------- *)(* AST phase 1 *)(* -------------------------------------------------------------------- *)(* try to better colorize identifiers which can be many different things
* e.g. a field, a type, a function, a parameter, etc
*)letast=tryAst_js_build.programcstwithAst_js_build.TodoConstruct_|Ast_js_build.UnhandledConstruct_->[]inletvisitor=Visitor_ast_js.mk_visitor{Visitor_ast_js.default_visitorwithVisitor_ast_js.ktop=(fun(k,_)t->(matchtwith|V{v_name=name;v_kind;v_init;v_resolved=_resolved}->letkind=Graph_code_js.kind_of_exprv_kindv_initintag_namename(Entity(kind,(Def2fake_no_def2)));|_->());kt);Visitor_ast_js.kprop=(fun(k,_)x->(matchxwith|Field(PNname,_,Fun_)->tag_namename(Entity(E.Method,(Def2fake_no_def2)));|Field(PNname,_,_)->tag_namename(Entity(E.Field,(Def2fake_no_def2)));|_->());kx);Visitor_ast_js.kexpr=(fun(k,_)x->(matchxwith|ObjAccess(_,PNname)->tag_namename(Entity(E.Field,(Use2fake_no_use2)));|IdSpecial(special,ii)->(matchspecialwith|Eval->tagiiBadSmell|_->tagiiBuiltin)|Id(name,scope)->(match!scopewith|NotResolved|Global_->tag_namename(Entity(E.Global,(Use2fake_no_use2)))|Local->tag_namename(H.LocalUse)|Param->tag_namename(H.ParameterUse));|Apply(Id(name,{contents=Global_|NotResolved}),_)->tag_namename(Entity(E.Function,(Use2fake_no_use2)));|Apply(Id(_name,{contents=Local|Param}),_)->(* todo: tag_name name PointerCall; *)()|Apply(ObjAccess(_,PNname),_)->tag_namename(Entity(E.Method,(Use2fake_no_use2)));|Fun(_,Somename)->tag_namename(Entity(E.Function,(Use2fake_no_use2)));|_->());kx);Visitor_ast_js.kstmt=(fun(k,_)x->(matchxwith|VarDecl({v_name=name;_})->tag_namename(H.LocalDef);|_->());kx);Visitor_ast_js.kparam=(fun(k,_)x->(matchxwith|{p_name=name;_}->tag_namename(H.ParameterDef););kx);}invisitor(Programast);(* -------------------------------------------------------------------- *)(* token phase 1 (individual tokens) *)(* -------------------------------------------------------------------- *)toks+>List.iter(funtok->matchtokwith(* specials *)(* less: could highlight certain words in the comment? *)|T.TCommentii->ifnot(Hashtbl.memalready_taggedii)thentagiiComment|T.TCommentSpace(_ii)|T.TCommentNewline(_ii)->()|T.TUnknown(ii)->tagiiError|T.EOF(_ii)->()(* values *)|T.T_NULL(ii)->tagiiH.Null|T.T_FALSE(ii)|T.T_TRUE(ii)->tagiiBoolean|T.T_NUMBER(_,ii)->tagiiNumber(* still? both strings and regular identifiers can be used to represent
* entities such as classes so have to look for both? *)|T.T_STRING(_,ii)|T.T_ENCAPSED_STRING(_,ii)->ifnot(Hashtbl.memalready_taggedii)thentagiiH.String|T.T_BACKQUOTEii->tagiiH.String|T.T_DOLLARCURLYii->tagiiH.String|T.T_REGEX(_,ii)->tagiiH.Regexp(* all the name and varname should have been tagged by now. *)|T.T_IDENTIFIER(_,ii)->ifnot(Hashtbl.memalready_taggedii)thentagiiError(* keywords *)|T.T_FUNCTION(ii)->tagiiKeyword|T.T_VAR(ii)|T.T_LET(ii)|T.T_CONST(ii)->tagiiKeyword|T.T_IF(ii)|T.T_SWITCH(ii)|T.T_ELSE(ii)->tagiiKeywordConditional|T.T_WHILE(ii)|T.T_DO(ii)|T.T_FOR(ii)->tagiiKeywordLoop|T.T_RETURN(ii)|T.T_BREAK(ii)|T.T_CONTINUE(ii)|T.T_CASE(ii)|T.T_DEFAULT(ii)->tagiiKeyword|T.T_IN(ii)|T.T_OF(ii)->tagiiKeyword|T.T_THIS(ii)|T.T_SUPER(ii)|T.T_INSTANCEOF(ii)|T.T_NEW(ii)|T.T_DELETE(ii)->tagiiKeywordObject|T.T_THROW(ii)|T.T_TRY(ii)|T.T_CATCH(ii)|T.T_FINALLY(ii)->tagiiKeywordExn|T.T_YIELDii|T.T_ASYNCii|T.T_AWAITii->tagiiKeyword|T.T_TYPEOF(ii)->tagiiKeyword|T.T_CLASSii|T.T_INTERFACEii|T.T_EXTENDSii|T.T_IMPLEMENTSii->tagiiKeywordObject|T.T_CONSTRUCTORii|T.T_GETii|T.T_SETii->tagiiKeywordObject|T.T_IMPORTii|T.T_EXPORTii|T.T_FROMii|T.T_ASii->tagiiKeywordModule|T.T_STATICii|T.T_WITH(ii)->tagiiKeyword|T.T_TYPEii|T.T_ENUMii|T.T_DECLAREii->tagiiKeyword|T.T_MODULEii->tagiiKeywordModule|T.T_PUBLICii|T.T_PRIVATEii|T.T_PROTECTEDii->tagiiKeywordObject|T.T_READONLYii->tagiiKeyword|T.T_VOID(ii)->tagiiTypeVoid|T.T_NUMBER_TYPE(ii)->tag_if_not_taggediiTypeInt|T.T_ANY_TYPEii|T.T_BOOLEAN_TYPEii|T.T_STRING_TYPEii->tag_if_not_taggedii(Entity(E.Type,Use2fake_no_use2))|T.T_XHP_TEXT(_,ii)->tagiiH.String|T.T_XHP_ATTR(_,ii)->tagii(Entity(E.Field,(Use2fake_no_use2)))|T.T_XHP_CLOSE_TAG(_,ii)->tagiiEmbededHtml|T.T_XHP_SLASH_GTii->tagiiEmbededHtml|T.T_XHP_GTii->tagiiEmbededHtml|T.T_XHP_OPEN_TAG(_,ii)->tagiiEmbededHtml(* Punctuation *)|T.T_LCURLY(ii)|T.T_RCURLY(ii)|T.T_LPAREN(ii)|T.T_LPAREN_ARROW(ii)|T.T_RPAREN(ii)|T.T_LBRACKET(ii)|T.T_RBRACKET(ii)|T.T_SEMICOLON(ii)|T.T_COMMA(ii)|T.T_PERIOD(ii)|T.T_DOTSii->tagiiPunctuation(* Operators *)|T.T_RSHIFT3_ASSIGN(ii)|T.T_RSHIFT_ASSIGN(ii)|T.T_LSHIFT_ASSIGN(ii)|T.T_BIT_XOR_ASSIGN(ii)|T.T_BIT_OR_ASSIGN(ii)|T.T_BIT_AND_ASSIGN(ii)|T.T_MOD_ASSIGN(ii)|T.T_DIV_ASSIGN(ii)|T.T_MULT_ASSIGN(ii)|T.T_MINUS_ASSIGN(ii)|T.T_PLUS_ASSIGN(ii)->tagiiPunctuation|T.T_ASSIGN(ii)->tagiiPunctuation|T.T_PLING(ii)|T.T_COLON(ii)->tagiiPunctuation|T.T_ARROWii->tagiiPunctuation|T.T_OR(ii)|T.T_AND(ii)|T.T_BIT_OR(ii)|T.T_BIT_XOR(ii)|T.T_BIT_AND(ii)|T.T_EQUAL(ii)|T.T_NOT_EQUAL(ii)|T.T_STRICT_EQUAL(ii)|T.T_STRICT_NOT_EQUAL(ii)|T.T_LESS_THAN_EQUAL(ii)|T.T_GREATER_THAN_EQUAL(ii)|T.T_LESS_THAN(ii)|T.T_GREATER_THAN(ii)|T.T_LSHIFT(ii)|T.T_RSHIFT(ii)|T.T_RSHIFT3(ii)|T.T_PLUS(ii)|T.T_MINUS(ii)|T.T_DIV(ii)|T.T_MULT(ii)|T.T_EXPONENT(ii)|T.T_MOD(ii)|T.T_NOT(ii)|T.T_BIT_NOT(ii)->tagiiOperator|T.T_INCR(ii)|T.T_DECR(ii)->tagiiPunctuation|T.T_VIRTUAL_SEMICOLON(_ii)->());(* -------------------------------------------------------------------- *)(* ast phase 2 *)()