/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . Ġand ĠKotlin ĠProgramming ĠLanguage Ġcontributors . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe Ġlicense / LICENSE . txt Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . idea . fir . low . level . api . element . builder Ċ Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġorg . jetbrains . kotlin . fir . F ir Element Ċ import Ġorg . jetbrains . kotlin . fir . declarations . F ir Declaration Ċ import Ġorg . jetbrains . kotlin . fir . declarations . F ir File Ċ import Ġorg . jetbrains . kotlin . fir . psi Ċ import Ġorg . jetbrains . kotlin . fir . real Psi Ċ import Ġorg . jetbrains . kotlin . fir . references .* Ċ import Ġorg . jetbrains . kotlin . fir . types . F ir ErrorType Ref Ċ import Ġorg . jetbrains . kotlin . fir . types . F ir Type Ref Ċ import Ġorg . jetbrains . kotlin . fir . types . F ir User Type Ref Ċ import Ġorg . jetbrains . kotlin . fir . types . impl . F ir Resolved Type Ref Impl Ċ import Ġorg . jetbrains . kotlin . fir . visitor s . F ir Visitor Void Ċ import Ġorg . jetbrains . kotlin . idea . fir . low . level . api . file . builder . Module File Cache Ċ import Ġorg . jetbrains . kotlin . idea . fir . low . level . api . util . isError Element Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġorg . jetbrains . kotlin . idea . util . getElement Text In Context Ċ import Ġorg . jetbrains . kotlin . psi .* Ċ Ċ /** Ċ Ġ* ĠBel ongs Ġto Ġa Ġ[ org . jetbrains . kotlin . idea . fir . low . level . api . F ir Module Resolve State ] Ċ Ġ*/ Ċ internal Ġclass ĠPsi To F ir Cache ( private Ġval Ġmodule File Cache : ĠModule File Cache ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcaches Ġ= ĠConcurrent HashMap < Kt File , ĠFile Cache >() ĊĊĠĠĠ Ġfun Ġget Cached Mapping ( element : ĠK t Element ): ĠF ir Element ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkt File Ġ= Ġelement . containing Kt File ĊĠĠĠĠĠĠĠ Ġval Ġcache Ġ= Ġcaches [ kt File ] ĊĠĠĠĠĠĠĠ Ġreturn Ġcache ?. get Cached Mapping ( element ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget F ir ( element : ĠK t Element , Ġcontainer F ir : ĠF ir Declaration , Ġfir File : ĠF ir File ): ĠF ir Element Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkt File Ġ= Ġelement . containing Kt File ĊĠĠĠĠĠĠĠ Ġval Ġcache Ġ= Ġcaches . get Or Put ( kt File ) Ġ{ ĠFile Cache ( kt File , Ġfir File , Ġmodule File Cache ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcache . getF ir ( element , Ġcontainer F ir ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// todo Ġfor Ġcompletion Ġonly ĊĠĠĠ Ġfun Ġrecord Elements For Completion From ( container F ir : ĠF ir Declaration , Ġfir File : ĠF ir File , Ġkt File : ĠK t File ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcache Ġ= Ġcaches . get Or Put ( kt File ) Ġ{ ĠFile Cache ( kt File , Ġfir File , Ġmodule File Cache ) Ġ} ĊĠĠĠĠĠĠĠ Ġcache . record Elements For Completion From ( container F ir ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ internal Ġclass ĠFile Cache ( val Ġkt File : ĠK t File , Ġfir File : ĠF ir File , Ġmodule File Cache : ĠModule File Cache ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcache : ĠConcurrent HashMap < Kt Element , ĠF ir Element > Ġ= ĠConcurrent HashMap () ĊĊĠĠĠ Ġfun Ġget Cached Mapping ( kt Element : ĠK t Element ): ĠF ir Element ? Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( kt Element . containing Kt File Ġ=== Ġkt File ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcache [ kt Element ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget F ir ( element : ĠK t Element , Ġcontainer F ir : ĠF ir Declaration ): ĠF ir Element Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpsi Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelement Ġis ĠK t Property Delegate Ġ-> Ġelement . expression Ġ?: Ġelement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelement Ġis ĠK t Qualified Expression Ġ&& Ġelement . selector Expression Ġis ĠK t Call Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK t Qualified Expression Ġwith ĠK t Call Expression Ġin Ġselector Ġtransformed Ġin ĠFIR Ġto ĠF ir Function Call Ġexpression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWhich Ġwill Ġhave Ġa Ġreceiver Ġas Ġqualifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelement . selector Expression Ġ?: Ġerror (" Incomplete Ġcode :\ n ${ element . getElement Text In Context () }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġelement ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcache [ psi ]?. let Ġ{ Ġreturn Ġit Ġ} ĊĠĠĠĠĠĠĠ Ġrecord Elements From ( container F ir ) ĊĊĠĠĠĠĠĠĠ Ġval Ġ( current , Ġmapped F ir ) Ġ= Ġpsi . getF ir Of Closest Parent () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġerror (" F ir Element Ġis Ġnot Ġfound Ġfor :\ n ${ element . getElement Text In Context () }") ĊĠĠĠĠĠĠĠ Ġif Ġ( current Ġ!== Ġelement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache ( current , Ġmapped F ir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġmapped F ir ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcache ( psi : ĠK t Element , Ġfir : ĠF ir Element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġtodo Ġmake Ġit Ġthread Ġsafe ĊĠĠĠĠĠĠĠ Ġval Ġexisting F ir Ġ= Ġcache [ psi ] ĊĠĠĠĠĠĠĠ Ġif Ġ( existing F ir Ġ!= Ġnull Ġ&& Ġexisting F ir Ġ!== Ġfir ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexisting F ir Ġis ĠF ir Type Ref Ġ&& Ġfir Ġis ĠF ir Type Ref Ġ&& Ġpsi Ġis ĠK t Type Reference Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠF ir Type Refs Ġare Ġoften Ġcreated Ġduring Ġresolve ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġlot Ġof Ġthem Ġwith Ġhave Ġthe Ġsame Ġsource ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġwant Ġto Ġtake Ġthe Ġmost Ġ" resolved Ġone " Ġhere ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( fir Ġis ĠF ir Resolved Type Ref Impl Ġ&& Ġexisting F ir Ġ! is ĠF ir Resolved Type Ref Impl ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache [ psi ] Ġ= Ġfir ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexisting F ir . isError Element Ġ&& Ġ! fir . isError Element Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO Ġbetter Ġhandle Ġerror Ġelements ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbut Ġfor Ġnow Ġjust Ġtake Ġfirst Ġnon - error Ġone Ġif Ġsuch Ġexist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache [ psi ] Ġ= Ġfir ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexisting F ir . isError Element Ġ|| Ġfir . isError Element Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdo Ġnothing Ġand Ġmaybe Ġupgrade Ġto Ġa Ġnon - error Ġelement Ġin Ġthe Ġbranch Ġabove Ġin Ġthe Ġfuture ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( D uplicated F ir Source Elements Exception . IS _ ENABLED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠD uplicated F ir Source Elements Exception ( existing F ir , Ġfir , Ġpsi ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( existing F ir Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache [ psi ] Ġ= Ġfir ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrecord Elements For Completion From ( fir Declaration : ĠF ir Declaration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrecord Elements From ( fir Declaration ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrecord Elements From ( fir Declaration : ĠF ir Declaration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfir Declaration . accept ( elements Recorder ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġelements Recorder Ġ= Ġobject Ġ: ĠF ir Visitor Void () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Element ( element : ĠF ir Element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( element . real Psi Ġas ? ĠK t Element )?. let Ġ{ Ġpsi Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache ( psi , Ġelement ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelement . accept Children ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Reference ( reference : ĠF ir Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Control Flow Graph Reference ( control Flow Graph Reference : ĠF ir Control Flow Graph Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Named Reference ( named Reference : ĠF ir Named Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Resolved Named Reference ( resolved Named Reference : ĠF ir Resolved Named Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Delegate Field Reference ( delegate Field Reference : ĠF ir Delegate Field Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Backing Field Reference ( back ing Field Reference : ĠF ir Backing Field Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Super Reference ( super Reference : ĠF ir Super Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit This Reference ( this Reference : ĠF ir This Reference ) Ġ{} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit ErrorType Ref ( error Type Ref : ĠF ir ErrorType Ref ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit User Type Ref ( user Type Ref : ĠF ir User Type Ref ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Type Ref . accept Children ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠK t Element . getF ir Of Closest Parent (): ĠPair < Kt Element , ĠF ir Element >? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent : ĠPsi Element ? Ġ= Ġthis ĊĠĠĠĠĠĠĠ Ġwhile Ġ( current Ġis ĠK t Element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmapped F ir Ġ= Ġcache [ current ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mapped F ir Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcurrent Ġto Ġmapped F ir ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Ġ= Ġcurrent . parent ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } ĊĊ