123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523(*
Copyright 2012-2025 Codinuum Software Lab <https://codinuum.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*)(* fact extractor *)[%%prepare_logger]moduleXlist=Diffast_misc.XlistmoduleXset=Diffast_misc.XsetmoduleLoc=Diffast_misc.LocmoduleAstml=Diffast_core.AstmlmoduleFact_base=Diffast_core.Fact_basemoduleSourcecode=Diffast_core.SourcecodemoduleTriple=Diffast_core.TriplemoduleL=Java_labelmoduleTree=Java_treemoduleCommon=Java_parsing.CommonmoduleFB=Fact_base.F(L)openFBletp_provides=mkjres"provides"letp_fqn=mkjres"fullyQualifiedName"letp_uqn=mkjres"unqualifiedName"letp_in_class=mkjres"inClass"letp_in_interface=mkjres"inInterface"letp_in_method=mkjres"inMethod"letp_in_constructor=mkjres"inConstructor"letp_in_statement=mkjres"inStatement"letp_in_invocation=mkjres"inInvocation"letp_in_instance_creation=mkjres"inInstanceCreation"letp_in_method_invocation=mkjres"inMethodInvocation"letp_in_ctor_invocation=mkjres"inCtorInvocation"letp_in_field=mkjres"inField"letp_in_enum=mkjres"inEnum"letp_in_extends=mkjres"inExtends"letp_in_throws=mkjres"inThrows"letp_in_return_type=mkjres"inReturnType"letp_in_variable_declaration=mkjres"inVariableDeclaration"letp_in_parameter=mkjres"inParameter"letp_in_staticinit=mkjres"inStaticInitializer"letp_in_instanceinit=mkjres"inInstanceInitializer"letp_cond_of=mkjres"conditionOf"letp_then_part_of=mkjres"thenPartOf"letp_else_part_of=mkjres"elsePartOf"letp_name=mkjres"name"letp_dimensions=mkjres"dimensions"letp_extended_name=mkjres"extendedName"letp_signature=mkjres"signature"letp_initializer=mkjres"initializer"letp_declared_by=mkjres"declaredBy"letp_requires=mkjres"requires"letp_successor=mkjres"successor"letp_nparams=mkjres"nParameters"letp_nargs=mkjres"nArguments"letp_is_va_meth=mkjres"isVariableArityMethod"letp_is_abst=mkjres"isAbstract"letp_identifier=mkjres"identifier"letp_qualifier=mkjres"qualifier"letp_id_offset=mkjres"identOffset"letp_id_length=mkjres"identLength"letp_expr_offset=mkjres"exprOffset"letp_expr_length=mkjres"exprLength"letgetlab=getlabletnode_filteroptionsnd=(* filter out inactive nodes *)ifoptions#fact_restricted_flagthenletlab=getlabndin(* L.is_statement lab || *)(* L.is_block lab || *)(* L.is_class lab || *)(* L.is_interface lab || *)(* L.is_enum lab || *)L.is_methodlab||L.is_fieldlab||L.is_ctorlab||(* L.is_staticinit lab || *)(* L.is_instanceinit lab || *)(* L.is_invocation_or_instance_creation lab *)falseelsetrueletxxx_to_simple_namecn=tryleti=String.indexncinString.subn0iwithNot_found->nletsignature_to_simple_namen=xxx_to_simple_name'('nletextended_name_to_simple_namen=xxx_to_simple_name'#'nletnode_pair_filteroptionsnd1nd2=(ifoptions#fact_restricted_flagthen(tryletplab=getlabnd2#initial_parentinL.is_variabledeclaratorplab&&nd2#pos=0with_->false)elsetrue)||((node_filteroptionsnd1)&&(node_filteroptionsnd2))letget_fqn=Tree.get_fqnletis_argumentnd=tryL.is_arguments(getlabnd#initial_parent)with_->falseletfindis_xxxchildren=letidx=ref(-1)inbegintryArray.iteri(funind->ifis_xxx(getlabnd)thenbeginidx:=i;raiseExitend)childrenwithExit->()end;if!idx>=0thenchildren.(!idx)elseraiseNot_foundletget_logical_nth_childndnth=letl=ref[]inArray.iteri(funix->if(nd#data#get_ordinali)=nththenl:=x::!l)nd#initial_children;List.rev!l[%%capture_pathclassextractoroptionscache_pathtree=object(self)inheritextractor_baseoptionscache_pathtree(* as super*)method!id="Java"valmutablepackage_name=""valstack=newSourcecode.stackmethod!scanner_body_before_subscanndlab(*entity*)_=ifL.is_scope_creatinglabthenstack#pushnd;ifL.is_packagedeclarationlabthenpackage_name<-L.get_namelabmethod!scanner_body_after_subscanndlabentity=ifL.is_scope_creatinglabthenstack#pop;ifnode_filteroptionsndthenbeginself#add(entity,p_is_a,mkjresnd#data#get_category);(* self#add (entity, p_file_digest, tree#encoded_source_digest); *)beginletid_loc=nd#data#id_locinifid_loc!=Loc.dummythenbeginletoffset=id_loc.Loc.start_offsetinletlength=id_loc.Loc.end_offset-offset+1inself#add(entity,p_id_offset,Triple.make_nn_int_literaloffset);self#add(entity,p_id_length,Triple.make_nn_int_literallength);endend;ifL.is_expressionlabthenbeginletloc=nd#data#src_locinifloc!=Loc.dummythenbeginletoffset=loc.Loc.start_offsetinletlength=loc.Loc.end_offset-offset+1inself#add(entity,p_expr_offset,Triple.make_nn_int_literaloffset);self#add(entity,p_expr_length,Triple.make_nn_int_literallength);endend;begintryArray.iteri(funic->letnth=nd#data#get_ordinaliinself#add(entity,p_childxnth,self#mkentityc))nd#initial_childrenwithNot_found->Array.iter(func->self#add(entity,p_child0,self#mkentityc))nd#initial_childrenend;beginXset.iter(funsucc->self#add(entity,p_successor,self#mkentitysucc))nd#data#successorsend;ifL.is_compilationunitlabthenbeginself#add(entity,p_in_file,self#fileentity);end;ifL.is_typedeclarationlabthenbeginself#add(entity,p_in_file,self#fileentity);self#add(entity,p_name,mklit(L.get_namelab));letfqn=get_fqnpackage_namendlabinself#add(entity,p_fqn,mklitfqn);leten=self#mkextnamefqninself#add(en,p_is_a,Triple.c_external_name);self#add(entity,p_provides,en);self#set_versionentity;(*
stack#register_global fqn nd
*)end;begintryletc_or_i=get_nearest_surrounding_xxxL.is_class_or_interfacendinifL.is_class(getlabc_or_i)thenself#add(entity,p_in_class,self#mkentityc_or_i)elseself#add(entity,p_in_interface,self#mkentityc_or_i)withNot_found->()end;ifL.is_methodlab||L.is_ctorlabthenbeginletsignature=L.annotation_to_string(Tree.get_annotationnd)inself#add(entity,p_signature,mklitsignature);letname=ifL.is_ctorlabthen"<init>"elseL.get_namelabinself#add(entity,p_name,mklitname);letnparams=ref0inletis_va=reffalseinbegintryArray.iter(func->ifL.is_parameters(getlabc)thenbeginnparams:=Array.lengthc#initial_children;letlast_param=c#initial_children.(!nparams-1)inis_va:=L.is_va_parameter(getlablast_param);raiseExitend)nd#initial_childrenwithExit->()end;self#add(entity,p_nparams,Triple.make_nn_int_literal!nparams);self#add(entity,p_extended_name,mklit(Printf.sprintf"%s#%d"name!nparams));if!is_vathenself#add(entity,p_is_va_meth,Triple.l_true);beginletis_abst=L.is_methodlab&&trymatchSourcecode.get_logical_nth_childnd6with|[||]->true|_->falsewith_->trueinifis_abstthenself#add(entity,p_is_abst,Triple.l_true);end;(*
stack#register name nd;
*)letfqn=get_fqnpackage_namendlabinself#add(entity,p_fqn,mklitfqn);leten=self#mkextnamefqninself#add(en,p_is_a,Triple.c_external_name);self#add(entity,p_provides,en);(*
stack#register_global fqn nd
*)endelsebeginself#add_surrounding_xxxL.is_methodndentityp_in_method;self#add_surrounding_xxxL.is_ctorndentityp_in_constructor;end;if(L.is_fieldlab)thenbeginletname=L.get_namelabinself#add(entity,p_name,mklitname);letis_private=List.exists(funn->[%debug_log"%s"n#data#label];matchgetlabnwith|L.Modifiers_->beginArray.exists(func->matchgetlabcwith|L.ModifierL.Modifier.Private->true|_->false)n#initial_childrenend|_->false)(get_logical_nth_childnd0)in[%debug_log"name=\"%s\" is_private=%B"nameis_private];ifis_privatethenstack#registernamendelsebeginletfqn=get_fqnpackage_namendlabinself#add(entity,p_fqn,mklitfqn);leten=self#mkextnamefqninself#add(en,p_is_a,Triple.c_external_name);self#add(entity,p_provides,en)end;(*
stack#register_global fqn nd
*)endelseself#add_surrounding_xxxL.is_fieldndentityp_in_field;self#add_surrounding_xxxL.is_statementndentityp_in_statement;self#add_surrounding_xxxL.is_parameterndentityp_in_parameter;self#add_surrounding_xxxL.is_invocationndentityp_in_invocation;self#add_surrounding_xxxL.is_instance_creationndentityp_in_instance_creation;(*
self#add_surrounding_xxx L.is_method_invocation nd entity p_in_method_invocation;
self#add_surrounding_xxx L.is_ctor_invocation nd entity p_in_ctor_invocation;
*)ifL.is_invocation_or_instance_creationlab(* && L.is_named lab*)thenbeginletename=tryL.get_namelabwithNot_found->""inifename<>""thenbeginself#add(entity,p_extended_name,mklitename);letesn=extended_name_to_simple_nameenameinself#add(entity,p_name,mklitesn);ifString.containsesn'.'thenself#add(entity,p_uqn,mklit(Xlist.last(String.split_on_char'.'esn)))end;letn=tryleti=String.indexename'#'inString.subename(i+1)((String.lengthename)-i-1)with_->tryletargs=findL.is_argumentsnd#initial_childreninstring_of_int(Array.lengthargs#initial_children)with_->""inifn<>""thenself#add(entity,p_nargs,Triple.make_literal~ty:Triple.LT_intn)end;ifL.is_parameterlab||is_argumentndthenbeginself#add(entity,Triple.p_nth,Triple.make_nn_int_literalnd#initial_pos)end;ifL.is_parameterlab||L.is_catch_parameterlabthenbeginself#add(entity,p_dimensions,Triple.make_nn_int_literal(L.get_dimslab))end;ifnot(L.is_enumlab)thenself#add_surrounding_xxxL.is_enumndentityp_in_enum;ifnot(L.is_extendslab)thenself#add_surrounding_xxxL.is_extendsndentityp_in_extends;ifnot(L.is_throwslab)thenself#add_surrounding_xxxL.is_throwsndentityp_in_throws;ifnot(L.is_localvariabledecllab)thenself#add_surrounding_xxxL.is_localvariabledeclndentityp_in_variable_declaration;ifL.is_fieldaccesslabthenself#add(entity,p_name,mklit(L.get_namelab));ifL.is_qualifierlab&&L.is_namelabthenself#add(entity,p_name,mklit(L.get_namelab));ifL.is_parameterlabthenbeginletname=L.get_namelabinstack#registernamend;self#add(entity,p_name,mklitname)end;ifL.is_iflabthenbeginself#add(self#mkentitynd#initial_children.(0),p_cond_of,entity);letthen_nd=nd#initial_children.(1)inself#add(self#mkentitythen_nd,p_then_part_of,entity);ifnd#initial_nchildren>2thenletelse_nd=nd#initial_children.(2)inself#add(self#mkentityelse_nd,p_else_part_of,entity)end;ifL.is_variabledeclaratorlabthenbeginifL.is_localvariabledecl(getlabnd#initial_parent)thenbeginletname=L.get_namelabinstack#registernamendend;ifnd#initial_nchildren>0thenletrhs_nd=nd#initial_children.(0)inself#add(entity,p_initializer,self#mkentityrhs_nd);end;(*if L.is_resource lab then begin
let name = L.get_name lab in
stack#register name nd
end;*)ifL.is_primarynamelabthenbeginletname=L.get_namelabintryself#add(entity,p_declared_by,self#mkentity(stack#lookupname))withNot_found->leten=self#mkextnamenameinself#add(en,p_is_a,Triple.c_external_name);self#add(entity,p_requires,en)end;ifL.is_namedlab&&L.is_typelabthenbeginletn=L.get_namelabinself#add(entity,p_name,mklitn);lets=tryString.subn0(String.indexn'<')with_->ninletln0=Xlist.last(String.split_on_char'.'s)inletln=Xlist.last(String.split_on_char'$'ln0)inself#add(entity,p_uqn,mklitln);end;ifL.is_typelabthenbeginletdims=L.get_dimensionslabinifdims>0thenself#add(entity,p_dimensions,Triple.make_nn_int_literaldims)end;ifL.is_named_origlabthenifL.is_methodlab||L.is_ctorlab||L.is_invocation_or_instance_creationlabthen()elseself#add(entity,p_name,mklit(L.get_namelab));ifL.is_ambiguous_namelabthenbeginletn=L.get_namelabinletq,i=matchList.rev(String.split_on_char'.'n)with|[]|[_]->"",n|h0::h1::_->h1,h0inself#add(entity,p_identifier,mkliti);ifq<>""thenself#add(entity,p_qualifier,mklitq);end;self#add_surrounding_xxxL.is_staticinitndentityp_in_staticinit;self#add_surrounding_xxxL.is_instanceinitndentityp_in_instanceinit;endend(* of class Java.Fact.extractor *)](* main function *)letextractoptionscache_pathtree=tryletextractor=newextractoroptionscache_pathtreeinextractor#set_lang_prefixAstml.java_prefix;extractor#extractwith|Triple.File_existss->Common.warning_msg"file exists: \"%s\""s|Triple.Lock_failed->Common.warning_msg"fact buffer is already locked."