/* Ċ Ġ* Ġ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 . cache s . track ers Ċ Ċ import Ġcom . intellij . lang . AST Node Ċ import Ġcom . intellij . openapi . Disposable Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . openapi . util . Key Ċ import Ġcom . intellij . openapi . util . Modification Tracker Ċ import Ġcom . intellij . openapi . util . Simple Modification Tracker Ċ import Ġcom . intellij . openapi . vfs . Virtual File Ċ import Ġcom . intellij . pom . P om Manager Ċ import Ġcom . intellij . pom . P om Model Aspect Ċ import Ġcom . intellij . pom . event . P om Model Event Ċ import Ġcom . intellij . pom . event . P om Model Listener Ċ import Ġcom . intellij . pom . tree . Tree Aspect Ċ import Ġcom . intellij . pom . tree . events . Tree ChangeEvent Ċ import Ġcom . intellij . pom . tree . events . impl . Change Info Impl Ċ import Ġcom . intellij . psi .* Ċ import Ġcom . intellij . psi . impl . Psi ManagerImpl Ċ import Ġcom . intellij . psi . impl . Psi Modification Tracker Impl Ċ import Ġcom . intellij . psi . impl . Psi Tree ChangeEvent Impl Ċ import Ġcom . intellij . psi . impl . Psi Tree ChangeEvent Impl . Psi EventType . CHILD _ MOVED Ċ import Ġcom . intellij . psi . impl . Psi Tree ChangeEvent Impl . Psi EventType . PROPERTY _ CHANGED Ċ import Ġcom . intellij . psi . impl . Psi Tree Change Pre processor Ċ import Ġcom . intellij . psi . util . Psi Modification Tracker Ċ import Ġcom . intellij . psi . util . Psi Tree Util Ċ import Ġorg . jetbrains . kotlin . analyzer . Module Descriptor Listener Ċ import Ġorg . jetbrains . kotlin . descriptors . Module Descriptor Ċ import Ġorg . jetbrains . kotlin . k doc . psi . api . K Doc Ċ import Ġorg . jetbrains . kotlin . psi .* Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . any Desc endant OfType Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . get Top most Parent OfType Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . is Ancestor Ċ Ċ val ĠK OT LIN _ CONSOLE _ KEY Ġ= ĠKey . create < Boolean >(" kotlin . console ") Ċ Ċ /** Ċ Ġ* ĠTested Ġin ĠOut Of Block Modification Test Generated Ċ Ġ*/ Ċ // ĠFIX ĠME ĠWHEN ĠB UNCH Ġ 1 9 3 ĠRE MOVED Ċ abstract Ġclass ĠKotlin Code Block Modification Listener Compat ( protected Ġval Ġproject : ĠProject ) Ġ: ĠPsi Tree Change Pre processor , ĠDis posable Ġ{ ĊĠĠĠ Ġprotected Ġval Ġmodification Tracker Impl : ĠPsi Modification Tracker Impl Ġ= ĊĠĠĠĠĠĠĠ ĠPsi Modification Tracker . SERVICE . getInstance ( project ) Ġas ĠPsi Modification Tracker Impl ĊĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġprotected Ġvar Ġkotlin Modification Tracker : ĠLong Ġ= Ġ 0 ĊĊĠĠĠ Ġprotected Ġlateinit Ġvar Ġkotlin OutOf Code Block Tracker Impl : ĠSimple Modification Tracker ĊĊĠĠĠ Ġlateinit Ġvar Ġkotlin OutOf Code Block Tracker : ĠMod ification Tracker ĊĊĠĠĠ Ġinternal Ġval Ġper Module OutOf Code Block Tracker Updater Ġ= ĠKotlin Module OutOf Code Block Modification Tracker . Updater ( project ) ĊĊĠĠĠ Ġprotected Ġfun Ġinit ( ĊĠĠĠĠĠĠĠ Ġtree Aspect : ĠTree Aspect , ĊĠĠĠĠĠĠĠ Ġinc O CB Counter : Ġ( Kt File ) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠ Ġpsi Modification Tracker Listener : ĠPsi Modification Tracker . Listener , ĊĠĠĠĠĠĠĠ Ġkotlin OutOf Code Block Tracker Producer : Ġ() Ġ-> ĠSimple Modification Tracker , ĊĠĠĠĠĠĠĠ Ġis Language Tracker Enabled : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġkotlin OutOf Code Block Tracker Impl Ġ= Ġkotlin OutOf Code Block Tracker Producer () ĊĠĠĠĠĠĠĠ Ġkotlin OutOf Code Block Tracker Ġ= Ġkotlin OutOf Code Block Tracker Impl ĊĠĠĠĠĠĠĠ Ġval Ġmodel Ġ= ĠP om Manager . getModel ( project ) ĊĠĠĠĠĠĠĠ Ġval Ġmessage Bus Connection Ġ= Ġproject . message Bus . connect ( this ) ĊĠĠĠĠĠĠĠ Ġmodel . add Model Listener ( object Ġ: ĠP om Model Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġis Aspect Change Inter esting ( aspect : ĠP om Model Aspect ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġaspect Ġ== Ġtree Aspect ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġmodel Changed ( event : ĠP om Model Event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchange Set Ġ= Ġevent . get Change Set ( tree Aspect ) Ġas ĠTree ChangeEvent ? Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkt File Ġ= Ġchange Set . root Element . psi . containing File Ġas ? ĠK t File Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinc File Modification Count ( kt File ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchanged Elements Ġ= Ġchange Set . changed Elements ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġskip Ġchange Ġif Ġit Ġcontains Ġonly Ġvirtual / fake Ġchange ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( changed Elements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġignore Ġformatting Ġ( wh ites p aces Ġetc ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Formatting Change ( change Set ) Ġ|| Ġis Comment Change ( change Set )) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġin Block Elements Ġ= Ġin Block Mod ifications ( changed Elements ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphysical Ġ= Ġkt File . is Physical ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( in Block Elements . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Bus Connection . deliver Immediate ly () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( physical Ġ&& Ġ! is Repl Line ( kt File . virtual File ) Ġ&& Ġkt File Ġ! is ĠK t TypeCode Fragment ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinc O CB Counter ( kt File ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkt File . inc OutOf Block Modification Count () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( physical ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Block Elements . forEach Ġ{ Ġit . containing Kt File . add In Block Modified Item ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( is Language Tracker Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( Psi Manager . getInstance ( project ) Ġas ĠPsi ManagerImpl ). add Tree Change Pre processor ( this ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġmessage Bus Connection . subscribe ( Psi Modification Tracker . TOPIC , Ġpsi Modification Tracker Listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtree Changed ( event : ĠPsi Tree ChangeEvent Impl ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! Psi Modification Tracker Impl . can A ffect Psi ( event )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠCopy Ġlogic Ġfrom ĠPsi Modification Tracker Impl . tree Changed (). ĠSome Ġout - of - code - block Ġevents Ġare Ġwritten Ġto Ġlanguage Ġmodification ĊĠĠĠĠĠĠĠ Ġ// Ġtracker Ġin ĠPsi Modification Tracker Impl Ġbut Ġdon 't Ġhave Ġcorrespond ent ĠP om Model Event . ĠIncrease Ġkotlin OutOf Code Block Tracker ĊĠĠĠĠĠĠĠ Ġ// Ġmanually Ġif Ġneeded . ĊĠĠĠĠĠĠĠ Ġval Ġout Of Code Block Ġ= Ġwhen Ġ( event . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPROPERTY _ CHANGED Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent . propertyName Ġ=== ĠPsi Tree ChangeEvent . PROP _ UN LOADED _ P SI Ġ|| Ġevent . propertyName Ġ=== ĠPsi Tree ChangeEvent . PROP _ ROOT S ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCH ILD _ MOVED Ġ-> Ġevent . old Parent Ġis ĠPsi Directory Ġ|| Ġevent . new Parent Ġis ĠPsi Directory ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġevent . parent Ġis ĠPsi Directory ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( out Of Code Block ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkotlin OutOf Code Block Tracker Impl . inc Modification Count () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdispose () Ġ{ ĊĠĠĠĠĠĠĠ Ġkotlin OutOf Code Block Tracker Impl . inc Modification Count () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġis Repl Line ( file : ĠVirtual File ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfile . getUser Data ( K OT LIN _ CONSOLE _ KEY ) Ġ== Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġinc File Modification Count ( file : ĠK t File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtracker Ġ= Ġfile . getUser Data ( PER _ FILE _ MO DIF ICATION _ TRACK ER ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġfile . put UserData If Absent ( PER _ FILE _ MO DIF ICATION _ TRACK ER , ĠSimple Modification Tracker ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtracker . inc Modification Count () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġin Block Mod ifications ( elements : ĠArray < AST Node >): ĠList < Kt Element > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen Ġa Ġcode Ġfragment Ġis Ġre parsed , ĠInt ellij Ġdoesn 't Ġdo Ġan ĠAST Ġdiff Ġand Ġcons iders Ġthe Ġentire ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcontents Ġto Ġbe Ġreplaced , Ġwhich Ġis Ġrepresented Ġin Ġa ĠPO M Ġevent Ġas Ġan Ġempty Ġlist Ġof Ġchanged Ġelements ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġelements . map Ġ{ Ġelement Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmodification Scope Ġ= Ġget Inside Code Block Modification Scope ( element . psi ) Ġ?: Ġreturn Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodification Scope . block Declaration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġis Specific Change ( change Set : ĠTree ChangeEvent , Ġpre condition : Ġ( AST Node ?) Ġ-> ĠBoolean ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchange Set . changed Elements . all Ġ{ Ġchanged Element Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchanges By Element Ġ= Ġchange Set . get Changes By Element ( changed Element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges By Element . affected Children . all Ġ{ Ġaffected Child Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! pre condition ( affected Child )) Ġreturn @ all Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchange By Child Ġ= Ġchanges By Element . get Change By Child ( affected Child ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ all Ġif Ġ( change By Child Ġis ĠChange Info Impl ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Child Ġ= Ġchange By Child . old Child ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpre condition ( old Child ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġis Comment Change ( change Set : ĠTree ChangeEvent ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Specific Change ( change Set ) Ġ{ Ġit Ġis ĠPsi Comment Ġ|| Ġit Ġis ĠK Doc Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġis Formatting Change ( change Set : ĠTree ChangeEvent ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Specific Change ( change Set ) Ġ{ Ġit Ġis ĠPsi WhiteSpace Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠHas Ġto Ġbe Ġaligned Ġwith Ġ[ get Inside Code Block Modification Scope ] Ġ: ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġresult Ġof Ġanalysis Ġhas Ġto Ġbe Ġreflected Ġin Ġdirty Ġscope , ĊĠĠĠĠĠĠĠĠ Ġ* Ġthe Ġonly Ġdifference Ġis Ġwh ites p aces Ġand Ġcomments ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġget Inside Code Block Modification Dirty Scope ( element : ĠPsi Element ): ĠPsi Element ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! element . is Physical ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdirty Ġscope Ġfor Ġwh ites p aces Ġand Ġcomments Ġis Ġthe Ġelement Ġitself ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠPsi WhiteSpace Ġ|| Ġelement Ġis ĠPsi Comment Ġ|| Ġelement Ġis ĠK Doc ) Ġreturn Ġelement ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġget Inside Code Block Modification Scope ( element )?. block Declaration ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Inside Code Block Modification Scope ( element : ĠPsi Element ): ĠBlock Modification Scope Element ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlambda Ġ= Ġelement . get Top most Parent OfType < Kt Lambda Expression >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( lambda Ġis ĠK t Lambda Expression ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlambda . get Top most Parent OfType < Kt Super Type Call Entry >() ?. get Top most Parent OfType < Kt Class Or Object >() ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( it , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblock Declaration Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK t Psi Util . get Top most Parent Of Types ( element , Ġ* BLOCK _ DECL AR ATION _ TYPES ) Ġas ? ĠK t Declaration Ġ?: Ġreturn Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK t Psi Util . get Top most Parent OfType < Kt Class Or Object >( element ) Ġas ? ĠK t Declaration Ġ?: Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġshould Ġnot Ġbe Ġlocal Ġdeclaration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Kt Psi Util . is Local ( block Declaration )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( block Declaration ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Named Function Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Declaration . visibility Modifier Type ()?. to Visibility () Ġ== ĠVis ibilities . PRIVATE ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtop Class Like Declaration ( block Declaration )?. let Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( it , Ġit ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Declaration . has Block Body ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcase Ġlike Ġ` fun Ġfoo (): ĠString Ġ{... < caret > ... }` ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġblock Declaration . body Expression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . take If Ġ{ Ġit . is Ancestor ( element ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠBlock Modification Scope Element ( block Declaration , Ġit ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( block Declaration . has Declared ReturnType ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcase Ġlike Ġ` fun Ġfoo (): ĠString Ġ= Ġb < caret > lab la ` ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġblock Declaration . initializer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . take If Ġ{ Ġit . is Ancestor ( element ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠBlock Modification Scope Element ( block Declaration , Ġit ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Property Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Declaration . visibility Modifier Type ()?. to Visibility () Ġ== ĠVis ibilities . PRIVATE ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtop Class Like Declaration ( block Declaration )?. let Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( it , Ġit ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Declaration . type Reference Ġ!= Ġnull ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġadding Ġannotations Ġto Ġaccessor Ġis Ġthe Ġsame Ġas Ġchange Ġcontract Ġof Ġproperty ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( element Ġ! is ĠK t Annotated Ġ|| Ġelement . annotation Entries . isEmpty ()) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproper Expression Ġ= Ġblock Declaration . access ors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull Ġ{ Ġ( it . initializer Ġ?: Ġit . body Expression ). is Ancestor ( element ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġblock Declaration . initializer ?. take If Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġname Ġreferences Ġchanges Ġin Ġproperty Ġinitializer Ġare ĠO CB , Ġsee ĠK T - 3 8 4 4 3 , ĠK T - 3 8 7 6 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . is Ancestor ( element ) Ġ&& Ġ! it . any Desc endant OfType < Kt Name Reference Expression >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( proper Expression Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdeclaration Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK t Psi Util . get Top most Parent Of Types ( block Declaration , ĠK t Class Or Object :: class . java ) Ġas ? ĠK t Element ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( declaration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( declaration , Ġproper Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Script Initializer Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( block Declaration . body Ġas ? ĠK t Call Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . lambda Arguments ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . last OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . get Lambda Expression () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . take If Ġ{ Ġit . is Ancestor ( element ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠBlock Modification Scope Element ( block Declaration , Ġit ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Class Initializer Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Declaration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take If Ġ{ Ġit . is Ancestor ( element ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġkt Class Initializer Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( Psi Tree Util . getParent OfType ( block Declaration , ĠK t Class Or Object :: class . java )) ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( it , Ġkt Class Initializer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Secondary Constructor Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock Declaration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take If Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . body Expression ?. is Ancestor ( element ) Ġ?: Ġfalse Ġ|| Ġit . get Deleg ation Call OrNull ()?. is Ancestor ( element ) Ġ?: Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ?. let Ġ{ Ġkt Constructor Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPsi Tree Util . getParent OfType ( block Declaration , ĠK t Class Or Object :: class . java )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBlock Modification Scope Element ( it , Ġkt Constructor ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Class Or Object Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( element ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Property , Ġis ĠK t Named Function Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( element Ġas ? ĠK t Modifier List Owner )?. visibility Modifier Type ()?. to Visibility () Ġ== ĠVis ibilities . PRIVATE ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBlock Modification Scope Element ( block Declaration , Ġblock Declaration ) Ġelse Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠBlock Modification Scope Element ( val Ġblock Declaration : ĠK t Element , Ġval Ġelement : ĠK t Element ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġis Block Declaration ( declaration : ĠK t Declaration ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBLOCK _ DECL AR ATION _ TYPES . any Ġ{ Ġit . is Instance ( declaration ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠBLOCK _ DECL AR ATION _ TYPES Ġ= ĠarrayOf < Class < out ĠK t Declaration >>( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK t Property :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK t Named Function :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK t Class Initializer :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK t Secondary Constructor :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK t Script Initializer :: class . java ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġval ĠPER _ FILE _ MO DIF ICATION _ TRACK ER Ġ= ĠKey < Simple Modification Tracker >(" FILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT ") Ċ Ċ val ĠK t File . per File Modification Tracker : ĠMod ification Tracker ĊĠĠĠ Ġget () Ġ= Ġput UserData If Absent ( PER _ FILE _ MO DIF ICATION _ TRACK ER , ĠSimple Modification Tracker ()) Ċ Ċ private Ġval ĠFILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT Ġ= ĠKey < Long >(" FILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT ") Ċ Ċ val ĠK t File . out Of Block Modification Count : ĠLong Ġby ĠNot Nullable UserData Property ( FILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT , Ġ 0 ) Ċ Ċ private Ġfun ĠK t File . inc OutOf Block Modification Count () Ġ{ ĊĠĠĠ Ġclear In Block Mod ifications () ĊĊĠĠĠ Ġval Ġcount Ġ= Ġget UserData ( FILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT ) Ġ?: Ġ 0 ĊĠĠĠ Ġput UserData ( FILE _ OUT _ OF _ BLOCK _ MO DIF ICATION _ COUNT , Ġcount Ġ+ Ġ 1 ) Ċ } Ċ Ċ /** Ċ Ġ* Ġin Block Mod ifications Ġis Ġa Ġcollection Ġof Ġblock Ġelements Ġthose Ġhave Ġin - block Ġmodifications Ċ Ġ*/ Ċ private Ġval ĠIN _ BLOCK _ MO DIF ICATION S Ġ= ĠKey < Mutable Collection < Kt Element >> (" IN _ BLOCK _ MO DIF ICATION S ") Ċ private Ġval ĠFILE _ IN _ BLOCK _ MO DIF ICATION _ COUNT Ġ= ĠKey < Long >(" FILE _ IN _ BLOCK _ MO DIF ICATION _ COUNT ") Ċ Ċ val ĠK t File . in Block Modification Count : ĠLong Ġby ĠNot Nullable UserData Property ( FILE _ IN _ BLOCK _ MO DIF ICATION _ COUNT , Ġ 0 ) Ċ Ċ val ĠK t File . in Block Mod ifications : ĠCollection < Kt Element > ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcollection Ġ= Ġget UserData ( IN _ BLOCK _ MO DIF ICATION S ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcollection Ġ?: Ġempty Set () ĊĠĠĠ Ġ} Ċ Ċ private Ġfun ĠK t File . add In Block Modified Item ( element : ĠK t Element ) Ġ{ ĊĠĠĠ Ġval Ġcollection Ġ= Ġput UserData If Absent ( IN _ BLOCK _ MO DIF ICATION S , Ġmutable Set Of ()) ĊĠĠĠ Ġsynchronized ( collection ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġneed ToAdd Block Ġ= Ġcollection . none Ġ{ Ġit . is Ancestor ( element , Ġstrict Ġ= Ġfalse ) Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( need ToAdd Block ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcollection . remove If Ġ{ Ġelement . is Ancestor ( it , Ġstrict Ġ= Ġfalse ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcollection . add ( element ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġcount Ġ= Ġget UserData ( FILE _ IN _ BLOCK _ MO DIF ICATION _ COUNT ) Ġ?: Ġ 0 ĊĠĠĠ Ġput UserData ( FILE _ IN _ BLOCK _ MO DIF ICATION _ COUNT , Ġcount Ġ+ Ġ 1 ) Ċ } Ċ Ċ fun ĠK t File . clear In Block Mod ifications () Ġ{ ĊĠĠĠ Ġval Ġcollection Ġ= Ġget UserData ( IN _ BLOCK _ MO DIF ICATION S ) ĊĠĠĠ Ġcollection ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġsynchronized ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }