/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 Ċ Ġ* Ċ Ġ* Ġ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 . Ċ Ġ*/ Ċ package Ġcom . tang . intellij . lua . psi Ċ Ċ import Ġcom . intellij . openapi . util . Key Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi File Ċ import Ġcom . intellij . psi . util . Psi Tree Util Ċ import Ġcom . tang . intellij . lua . Constants Ċ import Ġcom . tang . intellij . lua . comment . Lua Comment Util Ċ import Ġcom . tang . intellij . lua . comment . psi .* Ċ import Ġcom . tang . intellij . lua . comment . psi . api . Lua Comment Ċ import Ġcom . tang . intellij . lua . search . Search Context Ċ import Ġcom . tang . intellij . lua . stubs . index . Lua Class Index Ċ import Ġcom . tang . intellij . lua . ty .* Ċ import Ġjava . util .* Ċ Ċ open Ġclass ĠFound Lua Scope ( open Ġval Ġscope : ĠLua Scoped Type Tree Scope , Ġval Ġpsi Scoped Type Index : ĠInt ? Ġ= Ġnull ) Ċ Ċ interface ĠLua Scoped Type Tree Scope Ġ{ ĊĠĠĠ Ġval Ġpsi : ĠPsi Element ĊĠĠĠ Ġval Ġtree : ĠLua Scoped Type Tree ĊĠĠĠ Ġval Ġparent : ĠLua Scoped Type Tree Scope ? ĊĊĠĠĠ Ġfun Ġfind Name ( context : ĠSearch Context , Ġname : ĠString , Ġbefore Index : ĠInt ? Ġ= Ġnull ): ĠLua Scoped Type ? ĊĠĠĠ Ġfun Ġfind Owner ( context : ĠSearch Context ): ĠI Ty ? Ċ } Ċ Ċ interface ĠLua Scoped Type Tree Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtree Key Ġ= ĠKey . create < Scoped Type Tree >(" lua . object . tree . types ") ĊĊĠĠĠĠĠĠĠ Ġfun Ġget ( file : ĠPsi File ): ĠLua Scoped Type Tree ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file Ġ! is ĠLua Psi File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Tree Ġ= Ġfile . getUser Data ( tree Key ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Tree ?. should Rebuild () Ġ!= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file . is Contents Loaded ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠScoped Type Stub Tree ( file ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Tree ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . put UserData ( tree Key , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠF allback Ġto ĠP SI Ġtree ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠScoped Type Psi Tree ( file ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Tree ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . put UserData ( tree Key , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcurrent Tree ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfind Name ( context : ĠSearch Context , Ġpin : ĠPsi Element , Ġname : ĠString ): ĠLua Scoped Type ? ĊĠĠĠ Ġfun Ġfind Owner ( context : ĠSearch Context , Ġpin : ĠPsi Element ): ĠI Ty ? ĊĠĠĠ Ġfun Ġfind Scope ( element : ĠPsi Element ): ĠFound Lua Scope ? Ċ } Ċ Ċ private Ġclass ĠScoped Type Tree Scope ( override Ġval Ġpsi : ĠLua Type Scope , Ġoverride Ġval Ġtree : ĠScoped Type Tree , Ġoverride Ġval Ġparent : ĠScoped Type Tree Scope ?): ĠLua Scoped Type Tree Scope Ġ{ ĊĠĠĠ Ġprivate Ġval Ġtypes Ġ= ĠArrayList < Lua Scoped Type >( 0 ) ĊĠĠĠ Ġprivate Ġval Ġchild Scopes Ġ= ĠLinkedList < Scoped Type Tree Scope >() ĊĊĠĠĠ Ġprivate Ġvar Ġd umb Cached Owner : ĠI Ty ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġis D umb Owner Cached Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġvar Ġcached Owner : ĠI Ty ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġis Owner Cached Ġ= Ġfalse ĊĊĠĠĠ Ġfun Ġadd Child Scope ( scope : ĠScoped Type Tree Scope ) Ġ{ ĊĠĠĠĠĠĠĠ Ġchild Scopes . add ( scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd ( type : ĠLua Scoped Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtypes . add ( type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd All ( type : ĠCollection < Lua Scoped Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġtypes . addAll ( type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun ĠforEach ( action : Ġ( Lua Scoped Type ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtypes . forEach ( action ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun ĠforEach Indexed ( action : Ġ( index : ĠInt , ĠLua Scoped Type ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtypes . forEach Indexed ( action ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠindexOf ( type : ĠLua Scoped Type ): ĠInt ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġindex Ġ= Ġtypes . indexOf ( type ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( index Ġ>= Ġ 0 ) Ġindex Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget ( name : ĠString , Ġbefore Index : ĠInt ): ĠLua Scoped Type ? Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġbefore Index Ġ- Ġ 1 Ġdown To Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġtypes [ i ] ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type . name Ġ== Ġname ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtype ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget ( name : ĠString ): ĠLua Scoped Type ? Ġ{ ĊĠĠĠĠĠĠĠ Ġtypes . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . name Ġ== Ġname ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfind Name ( context : ĠSearch Context , Ġname : ĠString , Ġbefore Index : ĠInt ?): ĠLua Scoped Type ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġif Ġ( before Index Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget ( name , Ġbefore Index ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget ( name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( type Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtype ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcls : ĠI Ty ? Ġ= Ġfind Owner ( context ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( cls ?. is Anonymous Ġ== Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Tag Ġ= Ġif Ġ( cls Ġis ĠTy Serialized Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLua Class Index . find ( context , Ġcls . className ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( cls Ġis ĠTy Psi Doc Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcls . tag Class ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNeed Ġto Ġensure Ġwe Ġdon 't Ġcheck Ġthe Ġsame Ġscope Ġ* without * Ġbefore Index ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( class Tag Ġ!= Ġpsi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgeneric Def Ġ= ĠPsi Tree Util . get Stub Children OfType As List ( class Tag , ĠLua Doc Generic Def :: class . java ). first OrNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . name Ġ== Ġname ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( generic Def Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġgeneric Def ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġparent ?. find Name ( context , Ġname ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġguess Owner ( context : ĠSearch Context ): ĠI Ty ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( psi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLua Doc Tag Class Ġ-> Ġpsi . type ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLua Class Method Def Stat Ġ-> Ġpsi . guess Parent Type ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLua Closure Expr Ġ-> Ġpsi . guess Parent Type ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġparent ?. find Owner ( context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind D umb Owner ( context : ĠSearch Context ): ĠI Ty ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Owner Cached ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcached Owner ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( is D umb Owner Cached ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġd umb Cached Owner ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġguess Owner ( context ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( owner Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġd umb Cached Owner Ġ= Ġowner ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis D umb Owner Cached Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġowner ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Smart Owner ( context : ĠSearch Context ): ĠI Ty ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Owner Cached ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcached Owner ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġguess Owner ( context ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( owner Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcached Owner Ġ= Ġowner ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Owner Cached Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġowner ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfind Owner ( context : ĠSearch Context ): ĠI Ty ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( context . is D umb ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind D umb Owner ( context ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Smart Owner ( context ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠFound Scope ( override Ġval Ġscope : ĠScoped Type Tree Scope , Ġpsi Scoped Type Index : ĠInt ? Ġ= Ġnull ): ĠFound Lua Scope ( scope , Ġpsi Scoped Type Index ) Ċ Ċ private Ġabstract Ġclass ĠScoped Type Tree ( val Ġfile : ĠLua Psi File ) Ġ: ĠLua Recursive Visitor (), ĠLua Scoped Type Tree Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscope Key Ġ= ĠKey . create < Scoped Type Tree Scope >(" lua . object . tree . types . scope ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġmodification Stamp : ĠLong Ġ= Ġfile . modification Stamp ĊĊĠĠĠ Ġprivate Ġval Ġroot Scope Ġ= ĠScoped Type Tree Scope ( file , Ġthis , Ġnull ) ĊĠĠĠ Ġprivate Ġvar Ġcurrent Scope Ġ= Ġroot Scope ĊĊĠĠĠ Ġopen Ġfun Ġshould Rebuild (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmodification Stamp Ġ!= Ġfile . modification Stamp ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate ( psi : ĠLua Type Scope ): ĠScoped Type Tree Scope Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġgeneric Defs Ġ= Ġif Ġ( psi Ġis ĠLua Doc Function Ty ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpsi . generic Def List ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( psi Ġis ĠLua Doc Tag Alias ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpsi . generic Def List ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcomment Ġ= Ġif Ġ( psi Ġis ĠLua Comment Owner ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLua Comment Util . find Comment ( psi ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( psi Ġis ĠLua Doc Psi Element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLua Comment Util . find Container ( psi ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomment ?. find Generic Defs () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġscope Ġ= ĠScoped Type Tree Scope ( psi , Ġthis , Ġcurrent Scope ) ĊĊĠĠĠĠĠĠĠ Ġgeneric Defs ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscope . addAll ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġscope ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpush ( scope : ĠScoped Type Tree Scope ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Scope . addChild Scope ( scope ) ĊĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġscope ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpop () Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Scope . psi . put UserData ( scope Key , Ġcurrent Scope ) ĊĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġcurrent Scope . parent Ġ?: Ġroot Scope ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbuild Tree ( file : ĠPsi File ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfile . accept ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġabstract Ġoverride Ġfun Ġfind Scope ( element : ĠPsi Element ): ĠFound Scope ? ĊĊĠĠĠ Ġoverride Ġfun Ġfind Owner ( context : ĠSearch Context , Ġpin : ĠPsi Element ): ĠI Ty ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscope Source Element Ġ= Ġif Ġ( pin Ġis ĠLua Doc Psi Element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcomment Ġ= ĠLua Comment Util . find Container ( pin ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcls Ġ= Ġcomment . tag Class ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cls Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcls . type ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcomment . owner Ġ?: Ġpin ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpin ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfind Scope ( scope Source Element )?. scope ?. find Owner ( context ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfind Name ( context : ĠSearch Context , Ġpin : ĠPsi Element , Ġname : ĠString ): ĠLua Scoped Type ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind Scope ( pin )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . scope . find Name ( context , Ġname , Ġit . psi Scoped Type Index ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġopen Ġfun Ġtraverse Children ( element : ĠPsi Element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . visit Element ( element ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Element ( element : ĠPsi Element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠWARNING : Ġ( element Ġ! is ĠLua Doc Tag Class Ġ|| Ġcurrent Scope . psi Ġ! is ĠLua Doc Tag Class ) Ġis Ġused Ġinstead Ġof Ġ( element Ġ!= Ġcurrent Scope . psi ) ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠ Ġbecause ĠIDEA Ġgives Ġus Ġback ĠP SI Ġrepresenting Ġthe Ġsame Ġcontent Ġthat Ġare Ġ* not * Ġequal . ĊĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠLua Type Scope Ġ&& Ġ( element Ġ! is ĠLua Doc Tag Class Ġ|| Ġcurrent Scope . psi Ġ! is ĠLua Doc Tag Class )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpush ( create ( element )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Children ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpop () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( element Ġis ĠLua Doc Tag Over load Ġ&& Ġcurrent Scope . psi Ġ! is ĠLua Doc Tag Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTypically Ġgeneric Ġdefs Ġ(@ generic ) Ġare Ġscoped Ġto Ġthe Ġfunction Ġowner . ĠHowever , Ġover loads Ġare Ġa Ġspecial Ġcase ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhere Ġgener ics Ġdefs Ġmust Ġbe Ġscoped Ġto Ġthe Ġoverload Ġonly Ġi . e . Ġcannot Ġbe Ġreferenced Ġin Ġthe Ġfunction Ġbody . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Scope Ġ= Ġcurrent Scope ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġcurrent Scope . parent Ġ?: Ġroot Scope ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Children ( element ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġprevious Scope ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcls Ġ= Ġ( element Ġas ? ĠLua Comment )?. tag Class ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cls Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġencountered Ġa Ġcomment Ġwith Ġa Ġ@ class Ġthen Ġwe Ġwant Ġall Ġcomment Ġchildren Ġ( i . e . Ġ@ field ) Ġto Ġbe Ġchildren Ġof Ġthe Ġclass ' Ġscope . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpush ( create ( cls )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Children ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpop () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Children ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠScoped Type Psi Tree ( file : ĠLua Psi File ) Ġ: ĠScoped Type Tree ( file ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġfind Scope ( element : ĠPsi Element ): ĠFound Scope ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġpsi : ĠPsi Element ? Ġ= Ġelement ĊĠĠĠĠĠĠĠ Ġvar Ġpsi Scoped Type : ĠLua Scoped Type ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( psi Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( psi Scoped Type Ġ== Ġnull Ġ&& Ġpsi Ġis ĠLua Scoped Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpsi Scoped Type Ġ= Ġpsi ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidate Psi Ġ= Ġif Ġ( psi Ġis ĠLua Comment ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpsi . tag Class Ġ?: Ġpsi . owner Ġ?: Ġpsi ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpsi ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscope Ġ= Ġ( candidate Psi Ġas ? ĠLua Type Scope )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . getUser Data ( scope Key ) Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Tree ( element . containing File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidate Psi . getUser Data ( scope Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scope Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFound Scope ( scope , Ġpsi Scoped Type ?. let Ġ{ Ġscope . indexOf ( psi Scoped Type ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġpsi Ġ= Ġpsi . parent ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠScoped Type Stub Tree ( file : ĠLua Psi File ) Ġ: ĠScoped Type Tree ( file ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġshould Rebuild (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . should Rebuild () Ġ|| Ġ( file Ġas ? ĠLua Psi File )?. is Contents Loaded Ġ== Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtraverse Children ( element : ĠPsi Element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġstub : ĠST UB _ E LE ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠLua Psi File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstub Ġ= Ġelement . stub ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠST UB _ P SI ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstub Ġ= Ġelement . stub ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( stub Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( child Ġin Ġstub . children Stub s ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild . psi . accept ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . traverse Children ( element ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġfind Scope ( element : ĠPsi Element ): ĠFound Scope ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠST UB _ P SI ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġstub Ġ= Ġelement . stub ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpsi Scoped Type : ĠLua Scoped Type ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( stub Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstub Psi Ġ= Ġstub . psi ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( psi Scoped Type Ġ== Ġnull Ġ&& Ġstub Psi Ġis ĠLua Scoped Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpsi Scoped Type Ġ= Ġstub Psi ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscope Ġ= Ġ( stub Psi Ġas ? ĠLua Type Scope )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . getUser Data ( scope Key ) Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Tree ( element . containing File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstub Psi . getUser Data ( scope Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scope Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠFound Scope ( scope , Ġpsi Scoped Type ?. let Ġ{ Ġscope . indexOf ( psi Scoped Type ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstub Ġ= Ġstub . parent Stub ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠScoped Type Subst it utor ( context : ĠSearch Context , Ġval Ġscope : ĠLua Scoped Type Tree Scope ) Ġ: ĠTy Subst it utor () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġsubstitute ( context : ĠSearch Context , Ġclazz : ĠI Ty Class ): ĠI Ty Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ( clazz Ġas ? ĠTy Generic Parameter )?. let Ġ{ Ġgeneric Param Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscoped Ty Ġ= Ġscope . find Name ( context , Ġgeneric Param . varName )?. type Ġas ? ĠTy Generic Parameter ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scoped Ty ?. className Ġ== Ġgeneric Param . className ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġgeneric Ġparameter Ġwe Ġfound Ġis Ġthe Ġsame Ġas Ġthe Ġsource , Ġthen Ġwe 're Ġwithin Ġthe Ġscope Ġin Ġwhich Ġthe Ġgeneric Ġparameter Ġis Ġdefined . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġthis Ġscope , Ġthe Ġgeneric Ġparameter Ġis Ġa Ġconcrete Ġ( al beit Ġunknown ) Ġtype . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTy Class . create Concrete Generic Parameter ( generic Param ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgeneric Param ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġclazz ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġsubstitute ( context : ĠSearch Context , Ġty : ĠI Ty ): ĠI Ty Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . element ?. let Ġ{ Ġcontext Element Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLua Scoped Type Tree . get ( context Element . containing File )?. find Scope ( context Element )?. scope ?. let Ġ{ Ġscope Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġty . substitute ( context , ĠScoped Type Subst it utor ( context , Ġscope )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġty ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ