/* Ċ Ġ* ĠThis Ġfile Ġis Ġpart Ġof ĠM CP IDE , Ġlicensed Ġunder Ġthe ĠMIT ĠLicense Ġ( MIT ). Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġk en zier ocks Ġ< https :// ken zier ocks . me > Ċ Ġ* ĠCopyright Ġ( c ) Ġcontributors Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ Ġ* Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN Ċ Ġ* ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġme . ken zier ocks . m cp ide . util . types olve Ċ Ċ import Ġcom . github . jav ap ar ser . ast . Node Ċ import Ġcom . github . jav ap ar ser . ast . body . Type Declaration Ċ import Ġcom . github . jav ap ar ser . ast . node Types . Node WithType Parameters Ċ import Ġcom . github . jav ap ar ser . ast . type . Class Or Interface Type Ċ import Ġcom . github . jav ap ar ser . resolution . Un solved Symbol Exception Ċ import Ġcom . github . jav ap ar ser . resolution . declarations . Resolved Declaration Ċ import Ġcom . github . jav ap ar ser . symbols olver . model . resolution . Symbol Reference Ċ import Ġcom . github . jav ap ar ser . symbols olver . model . resolution . Type Solver Ċ Ċ type alias ĠFail Handler Ġ= Ġ( name : ĠString , Ġctx : ĠNode ) Ġ-> ĠString ? Ċ Ċ class ĠNode Type Finder ( ĊĠĠĠ Ġprivate Ġval Ġtype Solver : ĠType Solver Ċ ) Ġ{ ĊĊĠĠĠ Ġfun Ġrequire Type ( name : ĠString , Ġctx : ĠNode ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrequire Type Unless ( name , Ġctx ) Ġ{ Ġfalse Ġ} !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequire Ġresolved Ġtype , Ġunless , Ġon Ġexception , Ġ[ condition ] Ġreturns Ġ` false `. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġrequire Type Unless ( name : ĠString , Ġctx : ĠNode , Ġcross inline Ġcondition : Ġ( String ) Ġ-> ĠBoolean ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind Type ( name , Ġctx ) Ġ{ Ġn , Ġc Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdo Ġnot Ġfail Ġif Ġwe Ġcan Ġinstead Ġfind Ġa Ġmatching Ġtype - var ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcondition ( n ) Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind Type Var ( n , Ġc ) Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠUn solved Symbol Exception ( n , Ġc . java Class . name Ġ+ Ġ"@ " Ġ+ Ġc . token Range . flatMap Ġ{ Ġit . to Range () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfind Type Var ( name : ĠString , Ġctx : ĠNode ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgenerate Sequence ( ctx ) Ġ{ Ġit . parentNode . orElse ( null ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Is Instance < Node WithType Parameters <* >>() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . type Parameters . as Sequence () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. any Ġ{ Ġit . name AsString Ġ== Ġname Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfind Type ( name : ĠString , Ġctx : ĠNode , Ġfail Handler : ĠFail Handler Ġ= Ġ{ Ġ_, Ġ_ Ġ-> Ġnull Ġ}): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ctx Ġis ĠClass Or Interface Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthese Ġcan Ġbe Ġbug gy Ġ-- Ġtry Ġto Ġresolve Ġtheir Ġscope Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbut Ġif Ġthat Ġfails , Ġit Ġmay Ġbe ĠF QN ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ctx . scope . isPresent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscope Ġ= Ġctx . scope . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind Type ( scope . name AsString , Ġscope , Ġfail Handler )?. let Ġ{ Ġbase Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnow Ġwe Ġcan Ġsolve Ġ` name ` ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ("$ base .$ name "). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmaybe ĠF QN ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ( build F qn ( ctx )). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno , Ġit Ġwas Ġjust Ġun solved Ġentirely ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfail Handler ( name , Ġctx ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNo Ġscope , Ġcan Ġbe Ġsolved Ġas Ġnormal : ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdot Idx Ġ= Ġname . indexOf ('.') ĊĠĠĠĠĠĠĠ Ġif Ġ( dot Idx Ġ> Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMaybe Ġalready ĠF QN ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ( name ). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpossibly Ġnot , Ġtry Ġsolving Ġit Ġby Ġremoving Ġlast Ġpart Ġand Ġsolving , Ġthen Ġapp ending . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf qc Ġ= Ġfind Type ( name . substring ( 0 , Ġdot Idx ), Ġctx , Ġfail Handler ) Ġ?: Ġreturn Ġfail Handler ( name , Ġctx ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ("$ f qc .$ name "). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġcouldn 't Ġsolve Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfail Handler ( name , Ġctx ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġmaybe Ġjava . lang ? ĊĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type (" java . lang .$ name "). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġthis Ġname Ġshould Ġexist Ġin Ġthe Ġcontext , Ġtry Ġto Ġfind Ġit ĊĠĠĠĠĠĠĠ Ġ// Ġif Ġthere 's Ġno ĠCU , Ġbail Ġout ĊĠĠĠĠĠĠĠ Ġval Ġcompilation Unit Ġ= Ġctx . find Compilation Unit (). orElse ( null ) Ġ?: Ġreturn Ġfail Handler ( name , Ġctx ) ĊĠĠĠĠĠĠĠ Ġval Ġf qn By Pkg Ġ= Ġcompilation Unit . package Declaration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġ"${ it . name AsString }. $ name " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. orElse ( name ) ĊĠĠĠĠĠĠĠ Ġ// Ġmaybe Ġit Ġexists Ġin Ġthis Ġpackage ĊĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ( fq n By Pkg ). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġmaybe Ġit Ġexists Ġin Ġthe Ġimports ĊĠĠĠĠĠĠĠ Ġcompilation Unit . imports . forEach Ġ{ Ġimport Decl Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( import Decl . is Static ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( import Decl . is A ster isk ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ("${ import Decl . name AsString }. $ name "). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( import Decl . name AsString . substring After Last ('.') Ġ== Ġname ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ( import Decl . name AsString ). if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġmaybe Ġit 's Ġinside Ġthe ĠCU Ġsomewhere ? ĊĠĠĠĠĠĠĠ Ġvar Ġclosest Decl Ġ= Ġfind Ancestor F qn ( ctx ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( closest Decl Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Solver . try ToS olve Type ("${ closest Decl . fully QualifiedName . get ()}. $ name ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. if S olved Ġ{ Ġreturn Ġit . qualified Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdidn 't Ġwork , Ġstep Ġup wards Ġif Ġwe Ġcan ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosest Decl Ġ= Ġfind Ancestor F qn ( closest Decl ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġno Ġdice ĊĠĠĠĠĠĠĠ Ġreturn Ġfail Handler ( name , Ġctx ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Ancestor F qn ( ctx : ĠNode ): ĠType Declaration < *> ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġctx . find Ancestor ( Type Declaration :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . fully QualifiedName . isPresent Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. orElse ( null ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild F qn ( ctx : ĠClass Or Interface Type ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ctx . scope . isPresent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ"${ build F qn ( ctx . scope . get ()) }.${ ctx . name AsString }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġctx . name AsString ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġinline Ġfun Ġ< S Ġ: ĠResolved Declaration > ĠSymbol Reference < S >. if S olved ( block : Ġ( S ) Ġ-> ĠUnit ): ĠUnit Ġ{ ĊĠĠĠ Ġif Ġ( is S olved ) Ġ{ ĊĠĠĠĠĠĠĠ Ġblock ( corre sponding Declaration ) ĊĠĠĠ Ġ} Ċ } Ċ