// Ġ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 . 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 . util . Processing Context Ċ import Ġorg . jetbrains . annotations . Api Status Ċ import Ġorg . jetbrains . u ast . U Element Ċ import Ġorg . jetbrains . u ast . U Expression Ċ import Ġorg . jetbrains . u ast . expressions . U Injection Host Ċ import Ġorg . jetbrains . u ast . to U Element Of Expected Types Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* ĠGroups Ġall ĠU AST - based Ġreference Ġproviders Ġby Ġchunks Ġwith Ġthe Ġsame Ġpriority Ġand Ġsupported ĠU Element Ġtypes . Ċ Ġ*/ Ċ 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 Ġadapter Ġ= ĠU ast Reference Provider Adapter ( provider . supported U Element Types , Ġpattern , Ġprovider ) ĊĠ Ġthis . register Reference Provider ( u ast Type Pattern ( provider . supported U Element Types ), Ġadapter , Ġpriority ) Ċ } Ċ Ċ 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 ĠC ACHED _ U AST _ IN JECTION _ HOST : ĠKey < Optional < U Injection Host >> Ġ= ĠKey . create (" C ACHED _ U AST _ IN JECTION _ HOST ") Ċ private Ġval ĠC ACHED _ U AST _ EXPRESSION : ĠKey < Optional < U Expression >> Ġ= ĠKey . create (" C ACHED _ U AST _ EXPRESSION ") Ċ Ċ internal Ġval ĠREQUEST ED _ P SI _ ELEMENT : ĠKey < Psi Element > Ġ= ĠKey . create (" REQUEST ED _ P SI _ ELEMENT ") Ċ internal Ġval ĠUS AGE _ P SI _ ELEMENT : ĠKey < Psi Element > Ġ= ĠKey . create (" 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 ? Ġ{ ĊĠ Ġif Ġ( element Ġis ĠU Element ) Ġreturn Ġelement ĊĊĠ Ġif Ġ( supported U Element Types . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠ Ġval Ġrequired Type Ġ= Ġsupported U Element Types [ 0 ] ĊĠĠĠ Ġif Ġ( required Type Ġ== ĠU Injection Host :: class . java ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġget Cached U Element ( context , Ġelement , ĠU Injection Host :: class . java , ĠC ACHED _ U AST _ IN JECTION _ HOST ) ĊĠĠĠ Ġ} Ġelse Ġif Ġ( required Type Ġ== ĠU Expression :: class . java ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġget Cached U Element ( context , Ġelement , ĠU Expression :: class . java , ĠC ACHED _ U AST _ EXPRESSION ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġreturn Ġelement . to U Element Of Expected Types (* supported U Element Types . to Typed Array ()) Ċ } Ċ Ċ private Ġfun Ġ< T Ġ: ĠU Element > Ġget Cached U Element ( context : ĠProcessing Context , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelement : ĠPsi Element , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclazz : ĠClass < T >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Key : ĠKey < Optional < T >> ): ĠT ? Ġ{ ĊĠ Ġval Ġshared Context Ġ= Ġcontext . shared Context ĊĊĠ Ġval Ġu Element Ref Ġ= Ġshared Context . get ( cacheKey ) ĊĠ Ġif Ġ( u Element Ref Ġ!= Ġnull ) Ġreturn Ġu Element Ref . orElse ( null ) ĊĊĠ Ġval Ġnew U Element Ġ= Ġelement . to U Element Of Expected Types ( clazz ) ĊĠ Ġshared Context . put ( cacheKey , ĠOptional . of Nullable ( new U Element )) ĊĠ Ġreturn Ġnew U Element Ċ } Ċ Ċ 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 ElementType Pattern Adapter ( supported U Element Types ) ĊĊĠ Ġ// Ġoptim isation Ġuntil ĠIDEA - 2 1 1 7 3 8 Ġis Ġimplemented ĊĠ Ġif Ġ( supported U Element Types . size Ġ== Ġ 1 Ġ&& Ġsupported U Element Types [ 0 ] Ġ== Ġ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 Ċ } Ċ Ċ /** Ċ Ġ* Ġ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 , ĠU ast Reference By Usage Adapter ( usage Pattern , Ġprovider ), Ġpriority ) ĊĠ Ġ} Ċ }