package Ġcom . a em tools . analysis . ht l . call chain . raw chain processor Ċ Ċ import Ġcom . a em tools . analysis . ht l . Raw Chain Unit Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . Array Access Identifier Element Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . Base Chain Element Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . Call Chain Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . Call Chain Element Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . helper . chain Segment Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . segment . Base Call Chain Segment Ċ import Ġcom . a em tools . analysis . ht l . call chain . elements . segment . Call Chain Segment Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . Merged TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . base . Empty TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . base . TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . java . Array Java TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . java . Iterable Java TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . java . Java Psi Class TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . java . Map Java TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . pre defined . Pre defined TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . properties . Properties TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . template . Template Parameter TypeDescriptor Ċ import Ġcom . a em tools . analysis . ht l . call chain . type descriptor . template . Template TypeDescriptor Ċ import Ġcom . a em tools . code insight . ht l . model .* Ċ import Ġcom . a em tools . common . constant . const . java . W CM _ API _ COMPONENT Ċ import Ġcom . a em tools . common . util . has Child Ċ import Ġcom . a em tools . completion . ht l . common . Pre defined Variables Ċ import Ġcom . a em tools . completion . ht l . pre defined . H tl EL Pre defined . LIST _ AND _ REPEAT _ HELPER _ OBJECT Ċ import Ġcom . a em tools . lang . ht l . psi . H tl Array Like Access Ċ import Ġcom . a em tools . lang . ht l . psi . mixin . Access Identifier Mixin Ċ import Ġcom . a em tools . lang . ht l . psi . mixin . Variable Name Mixin Ċ import Ġcom . intellij . psi . Psi Class Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġjava . util . ArrayList Ċ import Ġjava . util . LinkedList Ċ Ċ /** Ċ Ġ* Ġ@ author ĠD my tro ĠPrim sh y ts Ċ Ġ*/ Ċ object ĠRaw Call Chain Processor Ġ{ ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠConvert Ġraw Ġcall Ġchain Ġinto Ġ[ Call Chain ]. ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġraw Chain Ġthe Ġraw Ġchain ĊĠĠ Ġ* Ġ@ return Ġcall Ġchain Ġinstance ĊĠĠ Ġ*/ ĊĠ Ġfun Ġprocess Chain ( raw Chain : ĠLinkedList < Raw Chain Unit >): ĠCall Chain Ġ{ ĊĠĠĠ Ġif Ġ( raw Chain . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġreturn ĠCall Chain . empty () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġsegments Ġ= ĠArrayList < Call Chain Segment >() ĊĊĠĠĠ Ġval Ġfirst Element : ĠRaw Chain Unit Ġ= Ġraw Chain . pop () ĊĊĠĠĠ Ġvar Ġfirst Segment Ġ= Ġextract First Segment ( first Element ) ĊĊĠĠĠ Ġsegments . add ( first Segment ) ĊĊĠĠĠ Ġwhile Ġ( raw Chain . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġoutput Type Ġ= Ġfirst Segment . output Type () ĊĠĠĠĠĠ Ġval Ġnew Segment Ġ= Ġwhen Ġ( output Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJava Psi Class TypeDescriptor Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġconstruct Typed Chain Segment ( output Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Chain . pop ()) ĊĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġconstruct Empty Chain Segment ( raw Chain . pop ()) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġsegments . add ( new Segment ) ĊĠĠĠĠĠ Ġfirst Segment Ġ= Ġnew Segment ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠCall Chain ( segments ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġextract First Segment ( raw Chain Unit : ĠRaw Chain Unit ): ĠCall Chain Segment Ġ{ ĊĠĠĠ Ġval Ġdeclaration Ġ= Ġraw Chain Unit . my Declaration ĊĊĠĠĠ Ġval Ġtype : ĠType Descriptor ? Ġ= Ġwhen Ġ( declaration ) Ġ{ ĊĠĠĠĠĠ Ġis ĠH tl Use Variable Declaration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġdeclaration . type Descriptor () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠH tl Template Declaration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ ĠTemplate TypeDescriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdeclaration . template Definition , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġraw Chain Unit . my Declaration . xml Attribute . project ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠH tl Template Parameter Declaration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ ĠTemplate Parameter TypeDescriptor ( declaration ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠH tl List Helper Declaration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ ĠPre defined TypeDescriptor ( LIST _ AND _ REPEAT _ HELPER _ OBJECT ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠH tl Variable Declaration Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ ĠType Descriptor . empty () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( type Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġconstruct Typed Chain Segment ( type , Ġraw Chain Unit ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġinput Type Ġ= Ġresolve First Type ( raw Chain Unit ) ĊĊĠĠĠ Ġif Ġ( input Type . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġreturn ĠCall Chain Segment . empty () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( input Type Ġis ĠJava Psi Class TypeDescriptor ĊĠĠĠĠĠĠĠ Ġ|| Ġinput Type Ġis ĠMerged TypeDescriptor ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( raw Chain Unit . my Call Chain . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġconstruct Typed Chain Segment ( input Type , Ġraw Chain Unit ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġreturn ĠBase Call Chain Segment ( input Type , Ġinput Type , Ġraw Chain Unit . my Declaration , Ġempty List ()) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġreturn ĠCall Chain Segment . empty () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠResolve Ġfirst Ġ[ Psi Class ] Ġof Ġfirst Ġcall Ġchain Ġsegment . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun Ġresolve First Type ( raw Chain Unit : ĠRaw Chain Unit ): ĠType Descriptor Ġ{ ĊĠĠĠ Ġval Ġelements Ġ= Ġraw Chain Unit . my Call Chain ĊĠĠĠ Ġval Ġfirst Element Ġ= Ġif Ġ( elements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġelements . first () Ġas ? Ġcom . a em tools . lang . ht l . psi . mixin . Variable Name Mixin ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġpsi Class : ĠPsi Class ? Ġ= Ġnull ĊĊĠĠĠ Ġif Ġ( psi Class Ġ== Ġnull Ġ&& Ġfirst Element Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġtype Ġ= ĠPre defined Variables . type Descriptor ById entifier ( first Element , Ġfirst Element . project ) ĊĠĠĠĠĠ Ġif Ġ( type Ġ! is ĠEmpty TypeDescriptor ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtype ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( psi Class Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġdeclaration Ġ= Ġraw Chain Unit . my Declaration ĊĠĠĠĠĠ Ġif Ġ( declaration Ġis ĠH tl Use Variable Declaration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdeclaration . type Descriptor () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġif Ġ( psi Class Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ ĠJava Psi Class TypeDescriptor ( psi Class , Ġnull , Ġnull ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠType Descriptor . empty () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconstruct Empty Chain Segment ( raw Chain Unit : ĠRaw Chain Unit ) ĊĠĠĠĠĠ Ġ: ĠCall Chain Segment Ġ= Ġchain Segment Ġ{ ĊĠĠĠ Ġthis . input Type Ġ= Ġinput Type ĊĠĠĠ Ġthis . declaration Type Ġ= Ġraw Chain Unit . my Declaration ĊĊĠĠĠ Ġval Ġraw Elements Ġ= ĠLinkedList ( raw Chain Unit . my Call Chain ) ĊĠĠĠ Ġval Ġresult : ĠArrayList < Call Chain Element > Ġ= ĠArrayList () ĊĠĠĠ Ġwhile Ġ( raw Elements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġnext Element Ġ= Ġraw Elements . pop () ĊĠĠĠĠĠ Ġval Ġelement Name Ġ= Ġextract ElementName ( nextElement ) ĊĊĠĠĠĠĠ Ġresult . add ( Base Chain Element ( ĊĠĠĠĠĠĠĠĠĠ Ġnext Element , ĊĠĠĠĠĠĠĠĠĠ Ġelement Name , ĊĠĠĠĠĠĠĠĠĠ ĠType Descriptor . empty () ĊĠĠĠĠĠ Ġ)) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġchain Ġ= Ġresult ĊĊĠĠĠ Ġthis . output Type Ġ= Ġresult . last (). type ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠCreate Ġtyped Ġchain Ġsegment . ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun Ġconstruct Typed Chain Segment ( input Type : ĠType Descriptor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Chain Unit : ĠRaw Chain Unit ): ĠCall Chain Segment Ġ= Ġchain Segment Ġ{ ĊĠĠĠ Ġthis . input Type Ġ= Ġinput Type ĊĠĠĠ Ġthis . declaration Type Ġ= Ġraw Chain Unit . my Declaration ĊĠĠĠ Ġval Ġraw Elements Ġ= ĠLinkedList ( raw Chain Unit . my Call Chain ) ĊĠĠĠ Ġval Ġresult : ĠArrayList < Call Chain Element > Ġ= ĠArrayList () ĊĊĠĠĠ Ġvar Ġcurrent Type : ĠType Descriptor Ġ= Ġinput Type ĊĠĠĠ Ġvar Ġcurrent Element Ġ= Ġraw Elements . pop () ĊĊĠĠĠ Ġvar Ġcall Chain Element Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠ Ġraw Chain Unit . my Declaration ?. attribute Type Ġ== ĠDeclaration AttributeType . LIST _ HELPER ĊĠĠĠĠĠĠĠĠĠ Ġ|| Ġraw Chain Unit . my Declaration ?. attribute Type Ġ== ĠDeclaration AttributeType . REPEAT _ HELPER Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ ĠBase Chain Element ( current Element , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġextract ElementName ( current Element ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPre defined TypeDescriptor ( LIST _ AND _ REPEAT _ HELPER _ OBJECT )) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġraw Chain Unit . my Declaration ?. type Ġ== ĠDeclaration Type . ITER ABLE ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġinput Type Ġis ĠArray Java TypeDescriptor Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġinput Type . array Type () ĊĠĠĠĠĠĠĠ ĠBase Chain Element ( current Element , Ġextract ElementName ( current Element ), Ġcurrent Type ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġraw Chain Unit . my Declaration ?. type Ġ== ĠDeclaration Type . ITER ABLE ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġinput Type Ġis ĠIterable Java TypeDescriptor Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġinput Type . iterable Type () ĊĠĠĠĠĠĠĠ ĠBase Chain Element ( current Element , Ġextract ElementName ( current Element ), Ġcurrent Type ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġraw Chain Unit . my Declaration ?. type Ġ== ĠDeclaration Type . ITER ABLE ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġinput Type Ġis ĠMap Java TypeDescriptor Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġinput Type . key Type () ĊĠĠĠĠĠĠĠ ĠBase Chain Element ( current Element , Ġextract ElementName ( current Element ), Ġcurrent Type ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġelse Ġ-> ĠBase Chain Element ( current Element , Ġextract ElementName ( current Element ), Ġcurrent Type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . add ( call Chain Element ) ĊĊĠĠĠ Ġwhile Ġ( raw Elements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġnext Raw Element Ġ= Ġraw Elements . pop () ĊĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Type . isArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġcurrent Type Ġis ĠArray Java TypeDescriptor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġnext Raw Element . has Child ( H tl Array Like Access :: class . java ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcall Chain Element Ġ= ĠArray Access Identifier Element ( next Raw Element ) ĊĠĠĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġcurrent Type . array Type () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Type . is Iterable () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġcurrent Type Ġis ĠIterable Java TypeDescriptor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġnext Raw Element . has Child ( H tl Array Like Access :: class . java ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcall Chain Element Ġ= ĠArray Access Identifier Element ( next Raw Element ) ĊĠĠĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġcurrent Type . iterable Type () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Type . is Map () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġcurrent Type Ġis ĠMap Java TypeDescriptor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġnext Raw Element . has Child ( H tl Array Like Access :: class . java ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcall Chain Element Ġ= ĠArray Access Identifier Element ( next Raw Element ) ĊĠĠĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġcurrent Type . valueType () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġhas Inner Properties TypeDescriptor ( next Raw Element , Ġcurrent Type ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Type Ġ= ĠProperties TypeDescriptor ( next Raw Element ) ĊĠĠĠĠĠĠĠĠĠ Ġcall Chain Element Ġ= ĠBase Chain Element ( next Raw Element , Ġ" properties ", Ġnew Type ) ĊĠĠĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġnew Type ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġvar Name Ġ= Ġextract ElementName ( next Raw Element ) ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Type Ġ= Ġcurrent Type . subtype ( varName ) ĊĠĠĠĠĠĠĠĠĠ Ġcall Chain Element Ġ= ĠBase Chain Element ( next Raw Element , Ġvar Name , Ġnew Type ) ĊĠĠĠĠĠĠĠĠĠ Ġcurrent Type Ġ= Ġnew Type ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġresult . add ( call Chain Element ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġchain Ġ= Ġresult ĊĊĠĠĠ Ġoutput Type Ġ= Ġresult . last (). type ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġextract ElementName ( element : ĠPsi Element ?): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠ Ġis ĠAccess Identifier Mixin Ġ-> Ġelement . variable Name () ĊĠĠĠĠĠ Ġis ĠVariable Name Mixin Ġ-> Ġelement . variable Name () ĊĠĠĠĠĠ Ġelse Ġ-> Ġ"" ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġhas Inner Properties TypeDescriptor ( next Raw Element : ĠPsi Element ?, Ġcurrent Type : ĠType Descriptor ) Ġ= ĊĠĠĠĠĠ Ġnext Raw Element Ġis ĠAccess Identifier Mixin ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġnext Raw Element . variable Name () Ġ== Ġ" properties " ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġcurrent Type Ġis ĠJava Psi Class TypeDescriptor ĊĠĠĠĠĠĠĠĠĠ Ġ&& Ġcurrent Type . qualified Name () Ġ== ĠW CM _ API _ COMPONENT Ċ Ċ } ĊĊ