/** Ċ Ġ* ĠCopyright Ġ 2 0 1 6 ĠNet flix , ĠInc . Ċ Ġ* Ċ Ġ* Ġ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 . netflix . rewrite . ast . visitor Ċ Ċ import Ġcom . netflix . rewrite . ast .* Ċ import Ġcom . netflix . rewrite . refactor . Ref actor Visitor Ċ Ċ /** Ċ Ġ* ĠOnly Ġformatting Ġfor Ġnodes Ġthat Ġwe Ġcan ĠADD Ġso Ġfar Ċ Ġ* Ġis Ġsupported . Ċ Ġ* Ċ Ġ* ĠEmit s Ġa Ġside - effect Ġof Ġmut ating Ġformatting Ġon Ġtree Ġnodes Ġas Ġnecessary Ċ Ġ*/ Ċ class ĠFormat Visitor : ĠRefactor Visitor < Tree >() Ġ{ ĊĠĠĠ Ġoverride Ġval Ġrule Name Ġ= Ġ" format " ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Compilation Unit ( cu : ĠTr . Compilation Unit ): ĠList < Ast Transform < Tree >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchanges Ġ= Ġmutable ListOf < Ast Transform < Tree >>() ĊĊĠĠĠĠĠĠĠ Ġ// Ġformat Ġchanges Ġin Ġimports ĊĠĠĠĠĠĠĠ Ġcu . imports . forEach Ġ{ Ġimport Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( import . formatting Ġis ĠFormat ting . Infer ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( import Ġ=== Ġcu . imports . last ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcu . classes . first OrNull ()?. let Ġ{ Ġclazz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( clazz . blank Lines Before ( 2 , Ġclazz )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( cu . imports . size Ġ> Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( import . blank Lines Before ( 1 , Ġimport )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( import Ġ=== Ġcu . imports . first ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( cu . package Decl Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( import . blank Lines Before ( 2 , Ġimport )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġprevious Ġfirst Ġimport Ġwill Ġlikely Ġhave Ġa Ġmultiple Ġline Ġspacing Ġprefix ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( cu . imports . size Ġ> Ġ 1 Ġ&& Ġcu . imports [ 1 ]. formatting Ġ! is ĠFormat ting . Infer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( cu . imports [ 1 ]. blank Lines Before ( 1 , Ġcu . imports [ 1 ])) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( import Ġ!== Ġcu . imports . last () Ġ&& Ġimport Ġ!== Ġcu . imports . first ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( import . blank Lines Before ( 1 , Ġimport )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcu . imports [ cu . imports . indexOf ( import ) Ġ+ Ġ 1 ]. let Ġ{ Ġnext Import Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges . addAll ( next Import . blank Lines Before ( 1 , Ġnext Import )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . visit Compilation Unit ( cu ) Ġ+ Ġchanges ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠFormat Ġadded Ġfields ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġvisit Multi Variable ( multi Variable : ĠTr . Variable Decl s ): ĠList < Ast Transform < Tree >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchanges Ġ= Ġif ( multi Variable . formatting Ġis ĠFormat ting . Infer ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġmake Ġa Ġsimpl ifying Ġassumption Ġhere Ġthat Ġinferred Ġvariable ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdeclaration Ġformatting Ġcomes Ġonly Ġfrom Ġadded Ġfields ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Body Ġ= Ġcursor (). parent (). last () Ġas ĠTr . Block < *> ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġindent s Ġ= Ġclass Body . statements ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map ( Tree :: formatting ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Is Instance < Formatting . Re ified >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . prefix . substring After Last ("\ n ") Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġindent Width ( c : ĠChar ) Ġ= Ġindent s . fold ( mutable Map Of < Int , ĠInt >()) Ġ{ Ġacc , Ġindent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġacc . merge ( indent . toCharArray (). count Ġ{ Ġit Ġ== Ġc Ġ}, Ġ 0 , ĠInt :: plus ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġacc ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. max With < Int , ĠInt >( Comparator Ġ{ Ġe 1 , Ġe 2 Ġ-> Ġe 1 . value . compareTo ( e 2 . value ) Ġ}) ?. key Ġ?: Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspace Indent Ġ= Ġindent Width (' Ġ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtab Indent Ġ= Ġindent Width ('\ t ') ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransform Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( space Indent Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Formatting ( format (( 1 .. space Indent ). join ToString ("", Ġprefix Ġ= Ġ"\ n ") Ġ{ Ġ" Ġ" Ġ})) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( tab Indent Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Formatting ( format (( 1 .. space Indent ). join ToString ("", Ġprefix Ġ= Ġ"\ n ") Ġ{ Ġ"\ t " Ġ})) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdefault Ġformatting Ġof Ġ 4 Ġspaces ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Formatting ( format ("\ n ĠĠĠ Ġ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġempty List () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . visit Multi Variable ( multi Variable ) Ġ+ Ġchanges ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠTree ?. blank Lines Before ( n : ĠInt , Ġtree : ĠTree Ġ= Ġcursor (). last ()): ĠList < Ast Transform < Tree >> Ġ{ ĊĠĠĠĠĠĠĠ Ġif ( this Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġempty List () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen ( formatting ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFormat ting . Re ified Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( prefix , Ġ_) Ġ= Ġformatting Ġas ĠFormat ting . Re ified ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġadd Ġblank Ġlines Ġif Ġnecessary ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadd Lines Ġ= Ġ( 1 .. Math . max ( 0 , Ġn Ġ- Ġprefix . take While Ġ{ Ġit Ġ== Ġ'\ n ' Ġ}. length )). map Ġ{ Ġ"\ n " Ġ}. join ToString ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġmodified Prefix Ġ= Ġ( add Lines Ġ+ Ġprefix ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġremove Ġextra Ġblank Ġlines Ġif Ġnecessary ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodified Prefix Ġ= Ġmodified Prefix . substring (( modified Prefix . take While Ġ{ Ġit Ġ== Ġ'\ n ' Ġ}. count () Ġ- Ġn )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( modified Prefix Ġ!= Ġprefix ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransform ( tree ) Ġ{ Ġchange Formatting ( formatting . with Prefix ( modified Prefix )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFormat ting . Infer , Ġis ĠFormat ting . None Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransform ( tree ) Ġ{ Ġchange Formatting ( format (( 1 .. n ). map Ġ{ Ġ"\ n " Ġ}. join ToString (" "))) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }