// ĠCopyright Ġ 2 0 0 0 - 2 0 1 8 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ @ file : Jvm Name (" U ast Reference Registrar ") Ċ Ċ package Ġcom . intellij . psi Ċ Ċ import Ġcom . intellij . code Insight . completion . Completion Util Core Impl Ċ import Ġcom . intellij . model . search . Search Service Ċ import Ġcom . intellij . openapi . util . Key Ċ import Ġcom . intellij . openapi . util . registry . Registry Ċ import Ġcom . intellij . patterns . Element Pattern Ċ import Ġcom . intellij . patterns . Standard Patterns Ċ import Ġcom . intellij . patterns . u ast . U Element Pattern Ċ import Ġcom . intellij . patterns . u ast . injection Host U Expression Ċ import Ġcom . intellij . psi . search . Local Search Scope Ċ import Ġcom . intellij . psi . util . Cached Value Provider Ċ import Ġcom . intellij . psi . util . Cached Value Provider . Result Ċ import Ġcom . intellij . psi . util . Cached Values Manager Ċ import Ġcom . intellij . psi . util . Psi Modification Tracker Ċ import Ġcom . intellij . util . Processing Context Ċ import Ġg nu . tro ve . TH ash Map Ċ import Ġorg . jetbrains . annotations . Api Status Ċ import Ġorg . jetbrains . u ast .* Ċ import Ġorg . jetbrains . u ast . expressions . U Injection Host Ċ Ċ private Ġval ĠCONTRIBUT OR _ CH UN KS _ KEY : ĠKey < Mutable Map < Chunk Tag , ĠU ast Reference Contributor Chunk >> Ġ= ĠKey . create (" u ast . psi Reference Contributor . chunks ") Ċ Ċ /** Ċ Ġ* ĠGroups Ġall ĠU AST - based Ġreference Ġproviders Ġby Ġchunks Ġwith Ġthe Ġsame Ġpriority Ġand Ġsupported ĠU Element Ġtypes . Ċ Ġ* ĠEnables Ġproper Ġcaching Ġof ĠU Element Ġfor Ġunderlying Ġreference Ġproviders . Ċ Ġ*/ Ċ fun ĠPsi Reference Registrar . register U ast Reference Provider ( pattern : Ġ( U Element , ĠProcessing Context ) Ġ-> ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprovider : ĠU ast Reference Provider , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriority : ĠDouble Ġ= ĠPsi Reference Registrar . DEFAULT _ PRIORITY ) Ġ{ ĊĠ Ġval Ġregist rar Ġ= Ġthis ĊĠ Ġvar Ġchunks Ġ= Ġregist rar . getUser Data ( CONTRIBUT OR _ CH UN KS _ KEY ) ĊĠ Ġif Ġ( chunks Ġ== Ġnull ) Ġ{ ĊĠĠĠ Ġchunks Ġ= ĠT HashMap () ĊĠĠĠ Ġregist rar . put UserData ( CONTRIBUT OR _ CH UN KS _ KEY , Ġchunks ) ĊĠ Ġ} ĊĊĠ Ġval Ġchunk Ġ= Ġchunks . get Or Put ( Chunk Tag ( priority , Ġprovider . supported U Element Types )) Ġ{ ĊĠĠĠ Ġval Ġnew Chunk Ġ= ĠU ast Reference Contributor Chunk ( provider . supported U Element Types ) ĊĠĠĠ Ġregist rar . register Reference Provider ( u ast Type Pattern ( provider . supported U Element Types ), Ġnew Chunk , Ġpriority ) ĊĠĠĠ Ġnew Chunk ĊĠ Ġ} ĊĠ Ġchunk . register ( pattern , Ġprovider ) Ċ } Ċ Ċ fun ĠPsi Reference Registrar . register U ast Reference Provider ( pattern : ĠElement Pattern < out ĠU Element >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprovider : ĠU ast Reference Provider , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriority : ĠDouble Ġ= ĠPsi Reference Registrar . DEFAULT _ PRIORITY ) Ġ{ ĊĠ Ġthis . register U ast Reference Provider ( pattern :: accept s , Ġprovider , Ġpriority ) Ċ } Ċ Ċ fun Ġu ast Injection Host Reference Provider ( provider : Ġ( U Expression , ĠPsi Language Injection Host ) Ġ-> ĠArray < Psi Reference >): ĠU ast Injection Host Reference Provider Ġ= ĊĠ Ġobject Ġ: ĠU ast Injection Host Reference Provider () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġget References For Injection Host ( u Expression : ĠU Expression , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhost : ĠPsi Language Injection Host , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext : ĠProcessing Context ): ĠArray < Psi Reference > Ġ= Ġprovider ( u Expression , Ġhost ) ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" u ast Injection Host Reference Provider ($ provider )" ĊĠ Ġ} Ċ Ċ fun Ġ< T Ġ: ĠU Element > Ġu ast Reference Provider ( cls : ĠClass < T >, Ġprovider : Ġ( T , ĠPsi Element ) Ġ-> ĠArray < Psi Reference >): ĠU ast Reference Provider Ġ= ĊĠ Ġobject Ġ: ĠU ast Reference Provider ( cls ) Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġget References By Element ( element : ĠU Element , Ġcontext : ĠProcessing Context ): ĠArray < Psi Reference > Ġ= ĊĠĠĠĠĠ Ġprovider ( cls . cast ( element ), Ġcontext [ REQUEST ED _ P SI _ ELEMENT ]) ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" u ast Reference Provider ($ provider )" ĊĠ Ġ} Ċ Ċ inline Ġfun Ġ< re ified ĠT Ġ: ĠU Element > Ġu ast Reference Provider ( no inline Ġprovider : Ġ( T , ĠPsi Element ) Ġ-> ĠArray < Psi Reference >): ĠU ast Reference Provider Ġ= ĊĠ Ġu ast Reference Provider ( T :: class . java , Ġprovider ) Ċ Ċ private Ġval Ġcached U Element Ġ= ĠKey . create < U Element >(" U ast Reference Registrar . cached U Element ") Ċ internal Ġval ĠREQUEST ED _ P SI _ ELEMENT Ġ= ĠKey . create < Psi Element >(" REQUEST ED _ P SI _ ELEMENT ") Ċ internal Ġval ĠUS AGE _ P SI _ ELEMENT Ġ= ĠKey . create < Psi Element >(" USAGE _ P SI _ ELEMENT ") Ċ Ċ internal Ġfun Ġget OrCreate Cached Element ( element : ĠPsi Element , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext : ĠProcessing Context ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsupported U Element Types : ĠList < Class < out ĠU Element >> ): ĠU Element ? Ġ= ĊĠ Ġelement Ġas ? ĠU Element Ġ?: Ġcontext ?. get ( cached U Element ) Ġ?: Ġsupported U Element Types . as Sequence (). map NotNull Ġ{ ĊĠĠĠ Ġelement . to U Element ( it ) ĊĠ Ġ}. first OrNull ()?. also Ġ{ Ġcontext ?. put ( cached U Element , Ġit ) Ġ} Ċ Ċ internal Ġfun Ġu ast Type Pattern ( supported U Element Types : ĠList < Class < out ĠU Element >> ): ĠElement Pattern < out ĠPsi Element > Ġ{ ĊĠ Ġval Ġu ast Type Pattern Ġ= ĠU ast Pattern Adapter ( supported U Element Types ) ĊĊĠ Ġ// Ġoptim isation Ġuntil ĠIDEA - 2 1 1 7 3 8 Ġis Ġimplemented ĊĠ Ġif Ġ( supported U Element Types Ġ== ĠlistOf ( U Injection Host :: class . java )) Ġ{ ĊĠĠĠ Ġreturn ĠStandard Patterns . instance Of ( Psi Language Injection Host :: class . java ). and ( u ast Type Pattern ) ĊĠ Ġ} ĊĊĠ Ġreturn Ġu ast Type Pattern Ċ } Ċ Ċ fun ĠElement Pattern < out ĠU Element >. as Psi Pattern ( var arg Ġsupported U Element Types : ĠClass < out ĠU Element >): ĠElement Pattern < Psi Element > Ġ= ĠU ast Pattern Adapter ( ĊĠ Ġif Ġ( supported U Element Types . isNotEmpty ()) Ġsupported U Element Types . toList () Ġelse ĠlistOf ( U Element :: class . java ), ĊĠ Ġthis :: accept s Ċ ) Ċ Ċ /** Ċ Ġ* ĠCreates ĠU AST Ġreference Ġprovider Ġthat Ġaccepts Ġadditional ĠP SI Ġelement Ġthat Ġcould Ġbe Ġeither Ġthe Ġsame Ġas Ġreference ĠP SI Ġelement Ġor Ġreference Ċ Ġ* Ġelement Ġthat Ġis Ġused Ġin Ġthe Ġsame Ġfile Ġand Ġsatisfy Ġusage Ġpattern . Ċ Ġ* Ċ Ġ* Ġ@ see Ġregister Reference Provider By Usage Ċ Ġ*/ Ċ @ Api Status . Experimental Ċ fun Ġu ast Reference Provider By Usage ( provider : Ġ( U Expression , Ġreference Psi : ĠPsi Language Injection Host , Ġusage Psi : ĠPsi Element ) Ġ-> ĠArray < Psi Reference >): ĠU ast Reference Provider Ġ= ĊĠ Ġobject Ġ: ĠU ast Reference Provider ( U Injection Host :: class . java ) Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġget References By Element ( element : ĠU Element , Ġcontext : ĠProcessing Context ): ĠArray < Psi Reference > Ġ{ ĊĠĠĠĠĠ Ġval Ġu Literal Ġ= Ġelement Ġas ? ĠU Expression Ġ?: Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĠĠĠĠĠ Ġval Ġhost Ġ= Ġcontext [ REQUEST ED _ P SI _ ELEMENT ] Ġas ? ĠPsi Language Injection Host Ġ?: Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĠĠĠĠĠ Ġval Ġusage Psi Ġ= Ġcontext [ USAGE _ P SI _ ELEMENT ] Ġ?: Ġcontext [ REQUEST ED _ P SI _ ELEMENT ] ĊĊĠĠĠĠĠ Ġreturn Ġprovider ( u Literal , Ġhost , Ġusage Psi ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" u ast By Usage Reference Provider ($ provider )" ĊĠ Ġ} Ċ Ċ /** Ċ Ġ* ĠRegisters Ġa Ġprovider Ġthat Ġwill Ġbe Ġcalled Ġon Ġthe Ġexpressions Ġthat Ġdirectly Ġsatisfy Ġthe Ġ[ usage Pattern ] Ġor Ġat Ġleast Ġone Ġof Ġthe Ġexpression Ċ Ġ* Ġusage s Ġsatisfies Ġthe Ġpattern Ġif Ġit Ġwas Ġassigned Ġto Ġa Ġvariable . ĠThe Ġprovider Ġwill Ġsearch Ġfor Ġusage s Ġof Ġvariables Ġonly Ġfor Ġexpressions Ġthat Ċ Ġ* Ġsatisfy Ġ[ expression Pattern ]. ĠThere Ġare Ġstandard Ġexpression Ġpatterns Ġfor Ġusage Ġsearch : Ġ[ u Injection Host In Variable ] Ġand Ġ[ u Expression In Variable ]. Ċ Ġ* Ċ Ġ* ĠConsider Ġusing Ġ[ u ast Reference Provider By Usage ] Ġif Ġyou Ġneed Ġto Ġobtain Ġadditional Ġcontext Ġfrom Ġa Ġusage Ġplace . Ċ Ġ*/ Ċ @ Api Status . Experimental Ċ fun ĠPsi Reference Registrar . register Reference Provider By Usage ( expression Pattern : ĠU Element Pattern < *, Ġ* >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġusage Pattern : ĠU Element Pattern < *, Ġ* >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprovider : ĠU ast Reference Provider , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpriority : ĠDouble Ġ= ĠPsi Reference Registrar . DEFAULT _ PRIORITY ) Ġ{ ĊĠ Ġthis . register U ast Reference Provider ( usage Pattern , Ġprovider , Ġpriority ) ĊĊĠ Ġif Ġ( Registry .` is ` (" u ast . references . by . usage ", Ġtrue )) Ġ{ ĊĠĠĠ Ġthis . register U ast Reference Provider ( expression Pattern , Ġobject Ġ: ĠU ast Reference Provider ( U Expression :: class . java ) Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġaccepts Target ( target : ĠPsi Element ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ! target . project . is Default Ġ&& Ġprovider . accept s Target ( target ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġget References By Element ( element : ĠU Element , Ġcontext : ĠProcessing Context ): ĠArray < Psi Reference > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsource Psi Ġ= Ġelement . source Psi Ġ?: Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĠĠĠĠĠĠĠ Ġval Ġoriginal U Element Ġ= Ġ( Completion Util Core Impl . get Original Element ( source Psi ) Ġ?: Ġsource Psi ). to U Element () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĊĠĠĠĠĠĠĠ Ġval Ġparent Variable Ġ= Ġwhen Ġ( val Ġu ast Parent Ġ= Ġoriginal U Element . u ast Parent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġis ĠU Variable Ġ-> Ġu ast Parent ĊĠĠĠĠĠĠĠĠĠ Ġis ĠU Poly adic Expression Ġ-> Ġu ast Parent . u ast Parent Ġas ? ĠU Variable Ġ// Ġsupport Ġ. with U ast Parent Or Self () Ġpatterns ĊĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( parent Variable Ġ== Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġparent Variable . name . isNull OrEmpty () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġ! parent Variable . type . equals ToText ( Common ClassNames . JAVA _ LANG _ STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġusage Ġ= Ġget Direct Variable Usage s ( parent Variable ). find Ġ{ Ġusage Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġval Ġref Expression Ġ= Ġusage . to U Element OfType < U Reference Expression >() ĊĠĠĠĠĠĠĠĠĠ Ġref Expression Ġ!= Ġnull Ġ&& Ġusage Pattern . accept s ( ref Expression , Ġcontext ) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġreturn ĠPsi Reference . EMPTY _ ARRAY ĊĊĠĠĠĠĠĠĠ Ġcontext . put ( USAGE _ P SI _ ELEMENT , Ġusage ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġprovider . get References By Element ( original U Element , Ġcontext ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" u ast Reference By Usage Adapter ($ provider )" ĊĠĠĠ Ġ}, Ġpriority ) ĊĠ Ġ} Ċ } Ċ Ċ @ Api Status . Experimental Ċ fun Ġu Injection Host In Variable () Ġ= Ġinjection Host U Expression (). filter Ġ{ ĊĠ Ġval Ġu ast Parent Ġ= Ġit . u ast Parent Ġ?: Ġget Original U ast Parent ( it ) ĊĠ Ġu ast Parent Ġis ĠU Variable Ċ } Ċ Ċ @ Api Status . Experimental Ċ fun Ġu Expression In Variable () Ġ= Ġinjection Host U Expression (). filter Ġ{ ĊĠ Ġval Ġu ast Parent Ġ= Ġit . u ast Parent Ġ?: Ġget Original U ast Parent ( it ) ĊĠ Ġu ast Parent Ġis ĠU Variable Ġ|| Ġ( u ast Parent Ġis ĠU Poly adic Expression Ġ&& Ġu ast Parent . u ast Parent Ġis ĠU Variable ) Ċ } Ċ Ċ private Ġfun Ġget Original U ast Parent ( element : ĠU Element ): ĠU Element ? Ġ{ ĊĠ Ġ// ĠKotlin Ġsends Ġnon - original Ġelement Ġon Ġcompletion ĊĠ Ġval Ġsrc Ġ= Ġelement . source Psi Ġ?: Ġreturn Ġnull ĊĠ Ġval Ġoriginal Ġ= ĠCompletion Util Core Impl . get Original Element ( src ) Ġ?: Ġsrc ĊĠ Ġreturn Ġoriginal . to U Element ()?. u ast Parent Ċ } Ċ Ċ private Ġfun Ġget Direct Variable Usage s ( u Var : ĠU Variable ): ĠCollection < Psi Element > Ġ{ ĊĠ Ġval Ġvariable Psi Ġ= Ġu Var . source Psi Ġ?: Ġreturn Ġempty List () ĊĠ Ġreturn ĠCached Values Manager . getManager ( variable Psi . project ). get Cached Value ( variable Psi , ĠCached Value Provider Ġ{ ĊĠĠĠ ĠResult . create Single Dependency ( find Direct Variable Usage s ( variable Psi ), ĠPsi Modification Tracker . MO DIF ICATION _ COUNT ) ĊĠ Ġ}) Ċ } Ċ Ċ private Ġfun Ġfind Direct Variable Usage s ( variable Psi : ĠPsi Element ): ĠCollection < Psi Element > Ġ{ ĊĠ Ġval Ġvariable Name Ġ= Ġvariable Psi . to U Element OfType < U Variable >() ?. name ĊĠ Ġif Ġ( variable Name . isNull OrEmpty ()) Ġreturn Ġempty List () ĊĠ Ġval Ġfile Ġ= Ġvariable Psi . containing File Ġ?: Ġreturn Ġempty List () ĊĊĠ Ġreturn ĠSearch Service . getInstance () ĊĠĠĠ Ġ. search Word ( variable Psi . project , Ġvariable Name ) ĊĠĠĠ Ġ. in Scope ( Local Search Scope ( array Of ( file ), Ġnull , Ġtrue )) ĊĠĠĠ Ġ. build Query Ġ{ Ġ_, Ġoccurrence Psi , Ġ_ Ġ-> ĊĠĠĠĠĠ Ġ// Ġwe Ġget Ġidentifiers Ġand Ġneed Ġto Ġprocess Ġtheir Ġparents , Ġsee ĠIDEA - 2 3 2 1 6 6 ĊĠĠĠĠĠ Ġval Ġu Ref Ġ= Ġoccurrence Psi . parent . find Containing ( U Reference Expression :: class . java ) ĊĠĠĠĠĠ Ġval Ġexpression Type Ġ= Ġu Ref ?. get Expression Type () ĊĠĠĠĠĠ Ġif Ġ( expression Type Ġ!= Ġnull Ġ&& Ġexpression Type . equals ToText ( Common ClassNames . JAVA _ LANG _ STRING )) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoccurrence Resolved Ġ= Ġu Ref . try Resolve (). to U Element ()?. source Psi ĊĠĠĠĠĠĠĠ Ġif Ġ( occ urrence Resolved Ġ!= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& ĠPsi Manager . getInstance ( occ urrence Psi . project ). are Elements Equivalent ( occ urrence Resolved , Ġvariable Psi )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġreturn @ build Query ĠlistOf NotNull ( u Ref . source Psi ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġempty List < Psi Element >() ĊĠĠĠ Ġ}. findAll () Ċ }