package Ġcom . step an ov . bbf . bug finder . tracer Ċ Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi File Ċ import Ġcom . intellij . psi . Psi WhiteSpace Ċ import Ġcom . step an ov . bbf . bug finder . executor . comp ilers . Mutation Checker Ċ import Ġcom . step an ov . bbf . bug finder . util . getType Ċ import Ġcom . step an ov . bbf . red uk tor . util .* Ċ import Ġorg . jetbrains . kotlin . psi .* Ċ import Ġorg . jetbrains . kotlin . psi . psi Util . is Property Parameter Ċ import Ġorg . jetbrains . kotlin . resolve . Binding Context Ċ Ċ class ĠVariable Values Tracer ( private Ġvar Ġtree : ĠPsi File , Ġprivate Ġval Ġctx : ĠBinding Context , Ġval Ġchecker : ĠMutation Checker ) Ġ{ ĊĊĠĠĠ Ġfun Ġtrace () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprop Params Ġ= Ġtree . getAll P SI Children OfType < Kt Parameter >(). filter Ġ{ Ġit . is Property Parameter () Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġproperties Ġ= Ġ( tree . getAll P SI Children OfType < Kt Property >() Ġ+ Ġprop Params ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name Ġ!= Ġnull Ġ&& Ġit . getType ( ctx )?. toString ()?. contains (" Int ") Ġ?: Ġfalse Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġprops With Pref Ġ= Ġproperties . map Ġ{ Ġprop Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġprefix Ġ= Ġgenerate Prefix ( prop ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prefix . isEmpty ()) Ġprefix Ġ= Ġ" global Var " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ prefix .${ prop . name }" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġprop To Print Ġ= Ġproperties . map Indexed Ġ{ Ġind , Ġprop Ġ-> Ġprop Ġto Ġcreate Print ( props With Pref [ ind ], Ġprop . name !! ) Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( node Ġin Ġtree . getAll DFS Children ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node Ġis ĠPsi WhiteSpace Ġ&& Ġnode . text . contains ("\ n ") Ġ&& Ġnode . parent Ġ! is ĠPsi File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbe aring Node Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" parent Ġ= Ġ${ node . parent . text }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs liced Ġ= Ġget Slice ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" sliced Ġ= Ġ${ sliced . map Ġ{ Ġit . text Ġ}} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprop To Print ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . first Ġin Ġs liced ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġit . second . text . contains (" global Var .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġ( it . first Ġis ĠK t Parameter Ġ&& Ġgenerate Prefix ( node ). contains ( generate Prefix ( it . first ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcopy Ġ= Ġit . second . copy () Ġas ĠK t Block Expression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġchecker . add Node If Possible With Node ( tree , Ġbe aring Node , Ġcopy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res Ġ!= Ġnull ) Ġbe aring Node Ġ= Ġres ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtrace ( line : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcur Line Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġprev : ĠPsi WhiteSpace ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġfor Ġ( node Ġin Ġtree . getAll DFS Children ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node Ġis ĠPsi WhiteSpace ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcur Line Ġ+= Ġnode . text . count Ġ{ Ġit Ġ== Ġ'\ n ' Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cur Line Ġ!= Ġline Ġ&& Ġnode . text . contains ("\ n ")) Ġprev Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node Ġis ĠPsi WhiteSpace Ġ&& Ġnode . text . contains ("\ n ") Ġ&& Ġnode . parent Ġ! is ĠPsi File ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cur Line Ġ!= Ġline ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbe aring Node Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// println (" parent Ġ= Ġ${ node . parent . text }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs liced Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( line Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev ?. let Ġ{ Ġget Slice ( it , Ġnode ) Ġ} Ġ?: Ġget Slice ( null , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Slice ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs liced WithName Ġ= Ġs liced . map Ġ{ Ġel Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġwhen Ġ( el ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Named Declaration Ġ-> Ġel . name Ġ?: Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġel . text ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġprefix Ġ= Ġgenerate Prefix ( el ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prefix . isEmpty ()) Ġprefix Ġ= Ġ" global Var " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ prefix .${ name }" Ġto Ġname ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs liced WithName ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprint Expr Ġ= Ġcreate Print ( it . first , Ġit . second ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcopy Ġ= Ġprint Expr . copy () Ġas ĠK t Block Expression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġchecker . add Node If Possible With Node ( tree , Ġbe aring Node , Ġcopy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res Ġ!= Ġnull ) Ġbe aring Node Ġ= Ġres ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgenerate Prefix ( prop : ĠPsi Element ) Ġ= ĊĠĠĠĠĠĠĠ Ġprop . getAll Parent sWith out This (). reversed () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit Ġis ĠK t Class Or Object Ġ|| Ġit Ġis ĠK t Named Function Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. join ToString (".") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Named Function Ġ-> Ġ" FUN _${ it . name }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠK t Class Or Object Ġ-> Ġ" CLASS _${ it . name }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġcreate Print ( name With Pref : ĠString , Ġname : ĠString ): ĠPsi Element Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠfullName Ġ= Ġif Ġ(! name With Pref . contains (" FUN ") Ġ&& Ġ! name With Pref . contains (" global Var ")) Ġ" this .$ name " Ġelse Ġname ĊĠĠĠĠĠĠĠ Ġval Ġblock Ġ= ĠK t Psi Factory ( project ). create Block (" println (\" VAR _ TR ACING : Ġ$ name With Pref Ġ= Ġ\ $$ fullName \") ") ĊĠĠĠĠĠĠĠ Ġblock . l Brace !!. delete () ĊĠĠĠĠĠĠĠ Ġblock . r Brace !!. delete () ĊĠĠĠĠĠĠĠ Ġreturn Ġblock ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠPsi Element . is Prop Param ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġthis Ġis ĠK t Parameter Ġ&& Ġthis . is Property Parameter () ĊĊĊĠĠĠ Ġprivate Ġfun Ġget Slice ( node From : ĠPsi Element ?, Ġnode To : ĠPsi Element ): ĠSet < Psi Element > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġslice Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtree . getAll DFS Children () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take While Ġ{ Ġit Ġ!= Ġnode To Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take Last While Ġ{ Ġnode From ?. let Ġ{ Ġnode From Ġ-> Ġit Ġ!= Ġnode From Ġ} Ġ?: Ġtrue Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġproperties Ġ= Ġslice . filter Is Instance < Kt Val Var Keyword Owner >() ĊĠĠĠĠĠĠĠ Ġif Ġ( properties . isNotEmpty ()) Ġreturn Ġproperties . toSet () ĊĠĠĠĠĠĠĠ Ġval Ġbinary Expr Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġslice . filter Ġ{ Ġit Ġis ĠK t Binary Expression Ġ&& Ġit . parent Ġ! in Ġslice Ġ}. map Ġ{ Ġit Ġas ĠK t Binary Expression Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( binary Expr . isNotEmpty ()) Ġreturn Ġbinary Expr . map NotNull Ġ{ Ġit . left Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Is Instance < Kt Name Reference Expression >(). toSet () ĊĠĠĠĠĠĠĠ Ġreturn Ġslice . filter Is Instance < Kt Name Reference Expression >(). filter Elements With Same Texts (). toSet () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġget Slice ( node : ĠPsi Element ): ĠSet < Psi Element > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġmutable Set Of < Psi Element >() ĊĠĠĠĠĠĠĠ Ġget Props Until ( node . parent , Ġnode ). forEach Ġ{ Ġres . add ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġnode . getAll Parent sWith out This (). zip With Next (). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Props Until ( it . second , Ġit . first ). forEach Ġ{ Ġres . add ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġres ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Props Until ( node : ĠPsi Element , Ġuntil : ĠPsi Element ) Ġ= ĊĠĠĠĠĠĠĠ Ġnode . getAll Children () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. take While Ġ{ Ġit Ġ!= Ġuntil Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit Ġis ĠK t Property Ġ|| Ġit . is Prop Param Ġ} ĊĊĊĠĠĠ Ġprivate Ġval Ġproject Ġ= Ġtree . project ĊĊ Ċ }