/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 5 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* Ġ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 Ġorg . jetbrains . kotlin . j 2 k Ċ Ċ import Ġcom . intellij . ide . util . Delegating Progress Indicator Ċ import Ġcom . intellij . lang . java . Java Language Ċ import Ġcom . intellij . openapi . diagnostic . Logger Ċ import Ġcom . intellij . openapi . editor . Range Marker Ċ import Ġcom . intellij . openapi . progress . Empty Progress Indicator Ċ import Ġcom . intellij . openapi . progress . Process Canceled Exception Ċ import Ġcom . intellij . openapi . progress . Progress Indicator Ċ import Ġcom . intellij . openapi . progress . Progress Manager Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . openapi . util . Text Range Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi File Ċ import Ġcom . intellij . psi . Psi Named Element Ċ import Ġcom . intellij . psi . Psi Reference Ċ import Ġcom . intellij . psi . impl . source . Dummy Holder Ċ import Ġorg . jetbrains . kotlin . diagnostics . Diagnostic Ċ import Ġorg . jetbrains . kotlin . diagnostics . Errors Ċ import Ġorg . jetbrains . kotlin . idea . Jet Language Ċ import Ġorg . jetbrains . kotlin . j 2 k . ast . Element Ċ import Ġorg . jetbrains . kotlin . j 2 k . usage Processing . Usage Processing Ċ import Ġorg . jetbrains . kotlin . psi .* Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . is Ancestor Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . parents Ċ import Ġorg . jetbrains . kotlin . resolve . Binding Context Ċ import Ġjava . util . ArrayList Ċ import Ġjava . util . Comparator Ċ import Ġjava . util . Linked HashMap Ċ import Ġkotlin . properties . Deleg ates Ċ Ċ public Ġtrait ĠPost Processor Ġ{ ĊĠĠĠ Ġpublic Ġfun Ġanalyze File ( file : ĠJet File , Ġrange : ĠText Range ?): ĠBinding Context ĊĊĠĠĠ Ġpublic Ġopen Ġfun Ġfix For Problem ( problem : ĠDiagnostic ): Ġ(() Ġ-> ĠUnit )? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpsi Element Ġ= Ġproblem . get Psi Element () ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( problem . get Factory ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠErrors . UN NE C ESS ARY _ NOT _ NULL _ ASSERT ION Ġ-> Ġ{ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġex cl Ex cl Op Ġ= Ġpsi Element Ġas ĠJet Simple Name Expression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġex cl Ex cl Expr Ġ= Ġex cl Ex cl Op . getParent () Ġas ĠJet Unary Expression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex cl Ex cl Expr . replace ( ex cl Ex cl Expr . getBase Expression () !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠErrors . VAL _ RE ASSIGN MENT Ġ-> Ġ{ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproperty Ġ= Ġ( psi Element Ġas ? ĠJet Simple Name Expression )?. getReference ()?. resolve () Ġas ? ĠJet Property ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( property Ġ!= Ġnull Ġ&& Ġ! property . is Var ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= ĠJet Psi Factory ( psi Element . getProject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty . get Val Or Var Node (). get Psi () !!. replace ( factory . create Var Node (). get Psi () !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġfun Ġdo Additional Processing ( file : ĠJet File , Ġrange Marker : ĠRange Marker ?) Ċ } Ċ Ċ public Ġenum Ġclass ĠParse Context Ġ{ ĊĠĠĠ ĠTOP _ LEVEL ĊĠĠĠ ĠCODE _ BLOCK Ċ } Ċ Ċ public Ġclass ĠJava To Kotlin Converter ( private Ġval Ġproject : ĠProject , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġsettings : ĠConverter Settings , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġreference Searcher : ĠReference Searcher , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġresolver For Converter : ĠResolver For Converter , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġpost Processor : ĠPost Processor ?) Ġ{ ĊĠĠĠ Ġprivate Ġval ĠLOG Ġ= ĠLogger . getInstance ("# org . jetbrains . kotlin . j 2 k . Java To Kotlin Converter ") ĊĊĠĠĠ Ġpublic Ġdata Ġclass ĠInput Element ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelement : ĠPsi Element , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpost Processing Context : ĠPsi Element ? ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġpublic Ġdata Ġclass ĠElement Result ( val Ġtext : ĠString , Ġ Ġval Ġparse Context : ĠParse Context ) ĊĊĠĠĠ Ġpublic Ġtrait ĠExternal Code Processing Ġ{ ĊĠĠĠĠĠĠĠ Ġpublic Ġfun Ġprepare Write Operation ( progress : ĠProgress Indicator ): Ġ() Ġ-> ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpublic Ġdata Ġclass ĠResult ( val Ġresults : ĠList < Element Result ? >, Ġval Ġexternal Code Processing : ĠExternal Code Processing ?) ĊĊĠĠĠ Ġpublic Ġfun Ġelements To Kotlin ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Elements : ĠList < InputElement >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprogress : ĠProgress Indicator Ġ= ĠEmpty Progress Indicator () ĊĠĠĠ Ġ): ĠResult Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġusage Process ings Ġ= ĠLinkedHashMap < Psi Element , ĠMutable Collection < Usage Processing >>() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġusage Processing Collector : Ġ( Usage Processing ) Ġ-> ĠUnit Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġusage Process ings . get Or Put ( it . target Element , Ġ{ ĠArrayList () Ġ}). add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġin Conversion Scope ( element : ĠPsi Element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ= Ġinput Elements . any Ġ{ Ġit . element . is Ancestor ( element , Ġstrict Ġ= Ġfalse ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprogress Text Ġ= Ġ" Con verting ĠJava Ġto ĠKotlin " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelement Count Ġ= Ġinput Elements . size () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Count Text Ġ= Ġelement Count . toString () Ġ+ Ġ" Ġ" Ġ+ Ġif Ġ( element Count Ġ> Ġ 1 ) Ġ" files " Ġelse Ġ" file " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfraction Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpass Ġ= Ġ 1 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġprocess Files With Progress < T Input Item , ĠT Output Item >( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfraction Port ion : ĠDouble , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Items : ĠIterable < T Input Item >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Item : Ġ( T Input Item ) Ġ-> ĠT Output Item ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠList < TO ut put Item > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Items Ġ= ĠArrayList < TO ut put Item >( element Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġuse Ġspecial Ġprocess Ġwith ĠEmpty Progress Indicator Ġto Ġavoid Ġchanging Ġtext Ġin Ġour Ġprogress Ġby Ġin her itors Ġsearch Ġinside Ġetc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProgress Manager . getInstance (). run Process ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . setText ("$ progress Text Ġ($ file Count Text ) Ġ- Ġpass Ġ$ pass Ġof Ġ 3 ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( i , Ġitem ) Ġin Ġinput Items . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . check Canceled () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . set Fraction ( fraction Ġ+ Ġfraction Port ion Ġ* Ġi Ġ/ Ġelement Count ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpsi File Ġ= Ġinput Elements [ i ]. element Ġas ? ĠPsi File ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( psi File Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . setText 2 ( psi File . get Virtual File (). get Present able Url ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Items . add ( process Item ( item )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpass ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfraction Ġ+= Ġfraction Port ion ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEmpty Progress Indicator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput Items ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintermediate Results Ġ= Ġprocess Files With Progress ( 0 . 2 5 , Ġinput Elements ) Ġ{ Ġinput Element Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠConverter . create ( input Element . element , Ġsettings , Ġ:: in Conversion Scope , Ġreference Searcher , Ġresolver For Converter , Ġusage Processing Collector ). convert () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. to ArrayList () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresults Ġ= Ġprocess Files With Progress ( 0 . 2 5 , Ġintermediate Results . with Index ()) Ġ{ Ġpair Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( i , Ġresult ) Ġ= Ġpair ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġintermediate Results [ i ] Ġ= Ġnull Ġ// Ġto Ġnot Ġhold Ġunused Ġobjects Ġin Ġthe Ġheap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠElement Result ( result . code Generator ( usage Process ings ), Ġresult . parse Context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexternal Code Processing Ġ= Ġbuild External Code Processing ( usage Process ings , Ġ:: in Conversion Scope ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( post Processor Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( progress Ġis ĠEmpty Progress Indicator , Ġ" Progress Ġindicator Ġnot Ġsupported Ġfor Ġpost Processor Ġ== Ġnull ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult ( results , Ġexternal Code Processing ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfinal Results Ġ= Ġprocess Files With Progress ( 0 . 5 , Ġresults . with Index ()) Ġ{ Ġpair Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( i , Ġresult ) Ġ= Ġpair ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// TODO : Ġpost Ġprocessing Ġdoes Ġnot Ġwork Ġcorrectly Ġfor ĠParse Context Ġdifferent Ġfrom ĠTOP _ LEVEL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkotlin File Ġ= ĠJet Psi Factory ( project ). create Analy z able File (" dummy . kt ", Ġresult . text , Ġinput Elements [ i ]. post Processing Context !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAfter Conversion Pass ( project , Ġpost Processor ). run ( kotlin File , Ġrange Ġ= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠElement Result ( kotlin File . getText (), Ġresult . parse Context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch ( e : ĠProcess Canceled Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . error ( t ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠResult ( final Results , Ġexternal Code Processing ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch ( e : ĠElement Creation StackTrace Required Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġwe Ġgot Ġthis Ġexception Ġthen Ġwe Ġneed Ġto Ġturn Ġelement Ġcreation Ġstack Ġtraces Ġon Ġto Ġget Ġbetter Ġdiagnostic ĊĠĠĠĠĠĠĠĠĠĠĠ ĠElement . save Creation Stack traces Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġelements To Kotlin ( input Elements ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠElement . save Creation Stack traces Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠReference Info ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreference : ĠPsi Reference , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget : ĠPsi Element , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile : ĠPsi File , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocess ings : ĠCollection < Usage Processing > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdepth : ĠInt Ġby ĠDeleg ates . lazy Ġ{ Ġtarget . parents ( with It self Ġ= Ġtrue ). take While Ġ{ Ġit Ġ! is ĠPsi File Ġ}. count () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild External Code Processing ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġusage Process ings : ĠMap < Psi Element , ĠCollection < Usage Processing >>, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Conversion Scope : Ġ( Psi Element ) Ġ-> ĠBoolean ĊĠĠĠ Ġ): ĠExternal Code Processing ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( usage Process ings . isEmpty ()) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġmap : ĠMap < Psi Element , ĠCollection < Usage Processing >> Ġ= Ġusage Process ings . values () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . java Code Processor Ġ!= Ġnull Ġ|| Ġit . kotlin Code Processor Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ Ġit . target Element Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( map . isEmpty ()) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġreturn Ġobject : ĠExternal Code Processing Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġprepare Write Operation ( progress : ĠProgress Indicator ): Ġ() Ġ-> ĠUnit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrefs Ġ= ĠArrayList < Reference Info >() ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . setText (" Searching Ġusage s Ġto Ġupdate ...") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( i , Ġentry ) Ġin Ġmap . entrySet (). with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpsi Element Ġ= Ġentry . key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocess ings Ġ= Ġentry . value ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . setText 2 (( psi Element Ġas ? ĠPsi Named Element )?. getName () Ġ?: Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress . check Canceled () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProgress Manager . getInstance (). run Process ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch Java Ġ= Ġprocess ings . any Ġ{ Ġit . java Code Processor Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch Kotlin Ġ= Ġprocess ings . any Ġ{ Ġit . kotlin Code Processor Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreference Searcher . find Usage s For External Code Processing ( psi Element , Ġsearch Java , Ġsearch Kotlin ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Not Ġ{ Ġin Conversion Scope ( it . getElement ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map To ( refs ) Ġ{ ĠReference Info ( it , Ġpsi Element , Ġit . getElement (). get Containing File (), Ġprocess ings ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProgress Port ion Reporter ( progress , Ġi Ġ/ Ġmap . size (). toDouble (), Ġ 1 . 0 Ġ/ Ġmap . size ())) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ{ Ġprocess Usage s ( refs ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Usage s ( refs : ĠCollection < Reference Info >) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( file Refs Ġin Ġrefs . groupBy Ġ{ Ġit . file Ġ}. values ()) Ġ{ Ġ// Ġgroup Ġby Ġfile Ġfor Ġfaster Ġsorting ĊĠĠĠĠĠĠĠĠĠĠĠ ĠReference Loop @ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( reference , Ġtarget , Ġfile , Ġprocess ings ) Ġin Ġfile Refs . sortBy ( Reference Comparator )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocessors Ġ= Ġwhen Ġ( reference . getElement (). get Language ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJava Language . INSTANCE Ġ-> Ġprocess ings . map Ġ{ Ġit . java Code Processor Ġ}. filter NotNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJet Language . INSTANCE Ġ-> Ġprocess ings . map Ġ{ Ġit . kotlin Code Processor Ġ}. filter NotNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcontinue @ Reference Loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Reference Valid ( reference ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġreferences Ġ= ĠlistOf ( reference ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( processor Ġin Ġprocessors ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreferences Ġ= Ġreferences . flatMap Ġ{ Ġprocessor . process Usage ( it ) Ġ?: ĠlistOf ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreferences . forEach Ġ{ Ġcheck Reference Valid ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Reference Valid ( reference : ĠPsi Reference ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġelement Ġ= Ġreference . getElement () ĊĠĠĠĠĠĠĠ Ġassert ( element . isValid () Ġ&& Ġelement . get Containing File () Ġ! is ĠDummy Holder ) Ġ{ Ġ" Reference Ġ$ reference Ġgot Ġinvalid ated " Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġobject ĠReference Comparator Ġ: ĠComparator < Reference Info > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcompare ( info 1 : ĠReference Info , Ġinfo 2 : ĠReference Info ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelement 1 Ġ= Ġinfo 1 . reference . getElement () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelement 2 Ġ= Ġinfo 2 . reference . getElement () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepth 1 Ġ= Ġinfo 1 . depth ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepth 2 Ġ= Ġinfo 2 . depth ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( depth 1 Ġ!= Ġdepth 2 ) Ġ{ Ġ// Ġput Ġdeeper Ġelements Ġfirst Ġto Ġnot Ġinvalidate Ġthem Ġwhen Ġprocessing Ġan cestors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ- depth 1 . compareTo ( depth 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprocess Ġelements Ġwith Ġthe Ġsame Ġparent Ġfrom Ġright Ġto Ġleft Ġso Ġthat Ġright - side Ġof Ġassignments Ġis Ġnot Ġinvalid ated Ġby Ġprocessing Ġof Ġthe Ġleft Ġone ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ- element 1 . getStart Offset In Parent (). compareTo ( element 2 . getStart Offset In Parent ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠProgress Port ion Reporter ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġindicator : ĠProgress Indicator , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġstart : ĠDouble , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġportion : ĠDouble ĊĠĠĠ Ġ) Ġ: ĠDeleg ating Progress Indicator ( indicator ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Fraction ( 0 . 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Fraction ( 0 . 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Fraction ( portion ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġset Fraction ( fraction : ĠDouble ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . set Fraction ( start Ġ+ Ġ( fraction Ġ* Ġportion )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Fraction (): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( super . get Fraction () Ġ- Ġstart ) Ġ/ Ġportion ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġset Text ( text : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġset Text 2 ( text : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ