/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 7 . Ġtang zx ( love . tang zx @ qq . 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 . Ċ Ġ*/ Ċ Ċ package Ġcom . tang . intellij . lua . psi Ċ Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi Manager Ċ import Ġcom . intellij . psi . util . Psi Tree Util Ċ import Ġcom . intellij . util . Processor Ċ import Ġcom . tang . intellij . lua . Constants Ċ import Ġcom . tang . intellij . lua . search . Search Context Ċ import Ġcom . tang . intellij . lua . stubs . index . Lua Class Member Index Ċ Ċ fun Ġresolve Local ( ref : ĠLua Name Expr , Ġcontext : ĠSearch Context ? Ġ= Ġnull ) Ġ= Ġresolve Local ( ref . name , Ġref , Ġcontext ) Ċ Ċ fun Ġresolve Local ( ref Name : String , Ġref : ĠPsi Element , Ġcontext : ĠSearch Context ? Ġ= Ġnull ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġval Ġelement Ġ= Ġresolve In File ( ref Name , Ġref , Ġcontext ) ĊĠĠĠ Ġreturn Ġif Ġ( element Ġis ĠLua Name Expr ) Ġnull Ġelse Ġelement Ċ } Ċ Ċ fun Ġresolve In File ( ref Name : String , Ġpin : ĠPsi Element , Ġcontext : ĠSearch Context ?): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġvar Ġret : ĠPsi Element ? Ġ= Ġnull ĊĠĠĠ ĠLua Declaration Tree . get ( pin . containing File ). walk Up ( pin ) Ġ{ Ġdecl Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( decl . name Ġ== Ġref Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġret Ġ= Ġdecl . first Declaration . psi ĊĠĠĠĠĠĠĠ Ġret Ġ== Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( ret Ġ== Ġnull Ġ&& Ġref Name Ġ== ĠConstants . WORD _ SELF ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmethod Def Ġ= ĠPsi Tree Util . get Stub Or Psi Parent OfType ( pin , ĠLua Class Method Def :: class . java ) ĊĠĠĠĠĠĠĠ Ġif Ġ( method Def Ġ!= Ġnull Ġ&& Ġ! method Def . is Static ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠmethodName Ġ= Ġmethod Def . class MethodName ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpr Ġ= ĠmethodName . expr ĊĠĠĠĠĠĠĠĠĠĠĠ Ġret Ġ= Ġif Ġ( expr Ġis ĠLua Name Expr Ġ&& Ġcontext Ġ!= Ġnull Ġ&& Ġexpr . name Ġ!= ĠConstants . WORD _ SELF ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolve ( expr , Ġcontext ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpr ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġret Ċ } Ċ Ċ fun Ġis Up Value ( ref : ĠLua Name Expr , Ġcontext : ĠSearch Context ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġfunc Body Ġ= ĠPsi Tree Util . getParent OfType ( ref , ĠLua Func Body :: class . java ) Ġ?: Ġreturn Ġfalse ĊĊĠĠĠ Ġval Ġref Name Ġ= Ġref . name ĊĠĠĠ Ġif Ġ( ref Name Ġ== ĠConstants . WORD _ SELF ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġclass Method Func Def Ġ= ĠPsi Tree Util . getParent OfType ( ref , ĠLua Class Method Def :: class . java ) ĊĠĠĠĠĠĠĠ Ġif Ġ( class Method Func Def Ġ!= Ġnull Ġ&& Ġ! class Method Func Def . is Static ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Func Body Ġ= Ġclass Method Func Def . func Body ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method Func Body Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmethod Func Body . text Offset Ġ< Ġfunc Body . text Offset ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġresolve Ġ= Ġresolve Local ( ref , Ġcontext ) ĊĠĠĠ Ġif Ġ( resolve Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! func Body . text Range . contains ( resolve . text Range )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġfalse Ċ } Ċ Ċ /** Ċ Ġ* ĠæŁ¥ æī¾ è¿Ļä¸ª å¼ķçĶ¨ Ċ Ġ* Ġ@ param Ġname Expr Ġ è¦ģ æŁ¥æī¾ çļĦ ref Ċ Ġ* Ġ* Ċ Ġ* Ġ@ param Ġcontext Ġcontext Ċ Ġ* Ġ* Ċ Ġ* Ġ@ return ĠPsi Element Ċ Ġ*/ Ċ fun Ġresolve ( name Expr : ĠLua Name Expr , Ġcontext : ĠSearch Context ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġ// search Ġlocal ĊĠĠĠ Ġvar Ġresolve Result Ġ= Ġresolve In File ( name Expr . name , Ġname Expr , Ġcontext ) ĊĊĠĠĠ Ġ// global ĊĠĠĠ Ġif Ġ( resolve Result Ġ== Ġnull Ġ|| Ġresolve Result Ġis ĠLua Name Expr ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġref Name Ġ= Ġname Expr . name ĊĠĠĠĠĠĠĠ Ġval ĠmoduleName Ġ= Ġname Expr . moduleName Ġ?: ĠConstants . WORD _ G ĊĠĠĠĠĠĠĠ ĠLua Class Member Index . process ( moduleName , Ġref Name , Ġcontext , ĠProcessor Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresolve Result Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġresolve Result Ċ } Ċ Ċ fun Ġmulti Resolve ( ref : ĠLua Name Expr , Ġcontext : ĠSearch Context ): ĠArray < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġlist Ġ= Ġmutable ListOf < Psi Element >() ĊĠĠĠ Ġ// search Ġlocal ĊĠĠĠ Ġval Ġresolve Result Ġ= Ġresolve In File ( ref . name , Ġref , Ġcontext ) ĊĠĠĠ Ġif Ġ( resolve Result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlist . add ( resolve Result ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġref Name Ġ= Ġref . name ĊĠĠĠĠĠĠĠ Ġval Ġmodule Ġ= Ġref . moduleName Ġ?: ĠConstants . WORD _ G ĊĠĠĠĠĠĠĠ ĠLua Class Member Index . process ( module , Ġref Name , Ġcontext , ĠProcessor Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġlist . to Typed Array () Ċ } Ċ Ċ fun Ġmulti Resolve ( index Expr : ĠLua Index Expr , Ġcontext : ĠSearch Context ): ĠList < Psi Element > Ġ{ ĊĠĠĠ Ġval Ġlist Ġ= Ġmutable ListOf < Psi Element >() ĊĠĠĠ Ġval Ġname Ġ= Ġindex Expr . name Ġ?: Ġreturn Ġlist ĊĠĠĠ Ġval Ġtype Ġ= Ġindex Expr . guess Parent Type ( context ) ĊĠĠĠ Ġtype . each Top Class ( Processor Ġ{ Ġty Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġm Ġ= Ġty . find Member ( name , Ġcontext ) ĊĠĠĠĠĠĠĠ Ġif Ġ( m Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( m ) ĊĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠ Ġ}) ĊĠĠĠ Ġif Ġ( list . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtree Ġ= ĠLua Declaration Tree . get ( index Expr . containing File ) ĊĠĠĠĠĠĠĠ Ġval Ġdeclaration Ġ= Ġtree . find ( index Expr ) ĊĠĠĠĠĠĠĠ Ġif Ġ( declaration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( declaration . psi ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġlist Ċ } Ċ Ċ fun Ġresolve ( index Expr : ĠLua Index Expr , Ġcontext : ĠSearch Context ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġval Ġname Ġ= Ġindex Expr . name Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġreturn Ġresolve ( index Expr , Ġname , Ġcontext ) Ċ } Ċ Ċ fun Ġresolve ( index Expr : ĠLua Index Expr , Ġid String : ĠString , Ġcontext : ĠSearch Context ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġval Ġtype Ġ= Ġindex Expr . guess Parent Type ( context ) ĊĠĠĠ Ġvar Ġret : ĠPsi Element ? Ġ= Ġnull ĊĠĠĠ Ġtype . each Top Class ( Processor Ġ{ Ġty Ġ-> ĊĠĠĠĠĠĠĠ Ġret Ġ= Ġty . find Member ( id String , Ġcontext ) ĊĠĠĠĠĠĠĠ Ġif Ġ( ret Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ Processor Ġfalse ĊĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠ Ġ}) ĊĠĠĠ Ġif Ġ( ret Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtree Ġ= ĠLua Declaration Tree . get ( index Expr . containing File ) ĊĠĠĠĠĠĠĠ Ġval Ġdeclaration Ġ= Ġtree . find ( index Expr ) ĊĠĠĠĠĠĠĠ Ġif Ġ( declaration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdeclaration . psi ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġret Ċ } Ċ Ċ /** Ċ Ġ* Ġ æī¾åĪ° Ġrequire ĠçļĦ æĸĩä»¶ è·¯å¾Ħ Ċ Ġ* Ġ@ param Ġpath String ĠåıĤæķ° åŃĹç¬¦ä¸² Ġrequire Ġ" aa . bb . cc " Ċ Ġ* Ġ* Ċ Ġ* Ġ@ param Ġproject ĠMy Project Ċ Ġ* Ġ* Ċ Ġ* Ġ@ return ĠPsi File Ċ Ġ*/ Ċ fun Ġresolve Require File ( path String : ĠString ?, Ġproject : ĠProject ): ĠLua Psi File ? Ġ{ ĊĠĠĠ Ġif Ġ( path String Ġ== Ġnull ) ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġval ĠfileName Ġ= Ġpath String . replace ('.', Ġ'/') ĊĠĠĠ Ġval Ġf Ġ= ĠLua File Util . find File ( project , ĠfileName ) ĊĠĠĠ Ġif Ġ( f Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpsi File Ġ= ĠPsi Manager . getInstance ( project ). find File ( f ) ĊĠĠĠĠĠĠĠ Ġif Ġ( psi File Ġis ĠLua Psi File ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpsi File ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġnull Ċ }