/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 6 Ġ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 . js . inline . clean Ċ Ċ import Ġorg . jetbrains . kotlin . js . backend . ast .* Ċ import Ġorg . jetbrains . kotlin . js . translate . utils . Js Ast Utils Ċ Ċ class ĠWhile Condition Fold ing ( val Ġbody : ĠJs Block ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġchanged Ġ= Ġfalse ĊĊĠĠĠ Ġfun Ġapply (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġbody . accept ( object Ġ: ĠRecursive Js Visitor () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Label ( x : ĠJs Label ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinner Statement Ġ= Ġx . statement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( inner Statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs While Ġ-> Ġprocess ( inner Statement , Ġx . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Do While Ġ-> Ġprocess ( inner Statement , Ġx . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġsuper . visit Label ( x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit While ( x : ĠJs While ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( x , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Do While ( x : ĠJs Do While ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( x , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġprocess ( statement : ĠJs While , Ġname : ĠJs Name ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( statement , Ġname , Ġ{ Ġfirst ( it ) Ġ}, Ġ{ Ġremove First ( it ) Ġ}, Ġ{ Ġa , Ġb Ġ-> ĠJs Ast Utils . and ( a , Ġb ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġprocess ( statement : ĠJs Do While , Ġname : ĠJs Name ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! has Continue ( statement . body , Ġname )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( statement , Ġname , Ġ{ Ġlast ( it ) Ġ}, Ġ{ Ġremove Last ( it ) Ġ}, Ġ{ Ġa , Ġb Ġ-> ĠJs Ast Utils . and ( b , Ġa ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġprocess ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement : ĠJs While , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname : ĠJs Name ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind : Ġ( Js Statement ) Ġ-> ĠJs Statement , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove : Ġ( Js Statement ) Ġ-> ĠJs Statement , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcombine : Ġ( Js Expression , ĠJs Expression ) Ġ-> ĠJs Expression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement . body . accept ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġoptimized Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġfind ( statement . body ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcondition Ġ= Ġextract Condition ( first , Ġname ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( condition Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement . body Ġ= Ġremove ( statement . body ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexisting Condition Ġ= Ġstatement . condition ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement . condition Ġ= Ġwhen Ġ( existing Condition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs Literal . TRUE Ġ-> Ġcondition ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcombine ( existing Condition , Ġcondition ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptimized Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( optimized ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠGets Ġcondition Ġfrom Ġwhile Ġor Ġdo .. while Ġbody Ġand Ġconvert Ġit Ġinto Ġwhile / do .. while Ġcondition ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠFor Ġexample , ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ Ġif Ġ(! A ) Ġbreak ; ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ ĠB () ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠThis Ġfunction Ġshould Ġreturn Ġ` A `, Ġ( neg ated Ġcondition Ġof Ġif Ġstatement ). ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġextract Condition ( statement : ĠJs Statement , Ġlabel : ĠJs Name ?): ĠJs Expression ? Ġ= Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCode Ġlike Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġwhile Ġ( A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ Ġbreak ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ ĠB (); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcan Ġbe Ġre written Ġas ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġwhile Ġ( A Ġ&& Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ ĠB (); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtherefore Ġfor Ġsingle Ġ` break ` Ġwe Ġshould Ġreturn Ġ` false `. ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Break Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Ġ= Ġstatement . label ?. name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( label Ġ== Ġtarget ) ĠJs Literal . FALSE Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCode Ġlike Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġwhile Ġ( A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ Ġif Ġ(! B ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠ ĠX ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ ĠD (); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhere ĠX Ġis Ġa Ġstatement , Ġand Ġwe Ġcan Ġextract Ġcondition Ġ` C ` Ġfrom Ġit , Ġcan Ġbe Ġre written Ġas ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġwhile Ġ( A Ġ&& Ġ( B Ġ|| ĠC )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ ĠD () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtherefore Ġwe Ġreturn ĠB Ġ|| ĠC ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġan Ġexample Ġis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġwhile Ġ( A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ Ġif Ġ(! B ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! C ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠĠ ĠD () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġapplying Ġthis Ġrule Ġrepeatedly Ġwe Ġget Ġwhile Ġ( A Ġ&& Ġ( B Ġ|| ĠC )), Ġwhich Ġis Ġcorrect ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs If Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġthen Ġ= Ġstatement . then Statement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statement . else Statement Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Condition Ġ= Ġextract Condition ( then , Ġlabel ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult : ĠJs Expression ? Ġ= Ġwhen Ġ( next Condition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠJust Ġa Ġlittle Ġoptimization . ĠWhen Ġinner Ġstatement Ġis Ġa Ġsingle Ġ` break `, Ġ` next Condition ` Ġwould Ġbe Ġfalse . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHowever , Ġ` A Ġ|| Ġfalse ` Ġcan Ġbe Ġre written Ġas Ġsimply Ġ` A ` ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJs Literal . FALSE Ġ-> ĠJs Ast Utils . not Optim ized ( statement . if Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠJs Ast Utils . or ( Js Ast Utils . not Optim ized ( statement . if Expression ), Ġnext Condition ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠA Ġsingle Ġblock Ġcontaining Ġa Ġstatement Ġwith Ġextract able Ġcondition ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Block Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statement . statements . size Ġ== Ġ 1 ) Ġextract Condition ( statement . statements [ 0 ], Ġlabel ) Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġfirst ( statement : ĠJs Statement ) Ġ= Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Block Ġ-> Ġstatement . statements . first OrNull () Ġ?: Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġremove First ( statement : ĠJs Statement ) Ġ= Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Block Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatements Ġ= Ġstatement . statements ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatements . remove At ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠJs Block () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġlast ( statement : ĠJs Statement ) Ġ= Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Block Ġ-> Ġstatement . statements . last OrNull () Ġ?: Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġfun Ġremove Last ( statement : ĠJs Statement ) Ġ= Ġwhen Ġ( statement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJs Block Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstatements Ġ= Ġstatement . statements ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statements . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatements . remove At ( statements . last Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠJs Block () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Function ( x : ĠJs Function ) Ġ{ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġchanged ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Continue ( statement : ĠJs Statement , Ġlabel : ĠJs Name ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġfound Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġstatement . accept ( object Ġ: ĠRecursive Js Visitor () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġvar Ġlevel Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Continue ( x : ĠJs Continue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġx . label ?. name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( name Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( level Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( name Ġ== Ġlabel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit For ( x : ĠJs For ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit For ( x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit While ( x : ĠJs While ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit While ( x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Do While ( x : ĠJs Do While ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit Do While ( x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit For In ( x : ĠJs For In ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit For In ( x ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Function ( x : ĠJs Function ) Ġ{ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Element ( node : ĠJs Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! found ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit Element ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġreturn Ġfound ĊĠĠĠ Ġ} Ċ }