import Ġcom . github . jav ap ar ser . Java Parser Ċ import Ġcom . github . jav ap ar ser . Parse Problem Exception Ċ import Ġcom . github . jav ap ar ser . Parse Start Ċ import Ġcom . github . jav ap ar ser . Parser Configuration Ċ import Ġcom . github . jav ap ar ser . Providers Ċ import Ġcom . github . jav ap ar ser . ast . Compilation Unit Ċ import Ġcom . github . jav ap ar ser . ast . NodeList Ċ import Ġcom . github . jav ap ar ser . ast . expr . Assign Expr Ċ import Ġcom . github . jav ap ar ser . ast . expr . Binary Expr Ċ import Ġcom . github . jav ap ar ser . ast . expr . Expression Ċ import Ġcom . github . jav ap ar ser . ast . expr . MethodCall Expr Ċ import Ġcom . github . jav ap ar ser . ast . expr . Name Expr Ċ import Ġcom . github . jav ap ar ser . ast . expr . Unary Expr Ċ import Ġcom . github . jav ap ar ser . ast . visitor . Void Visitor Adapter Ċ import Ġcom . github . jav ap ar ser . resolution . types . Resolved Primitive Type Ċ import Ġcom . github . jav ap ar ser . symbols olver . Java Symbol Solver Ċ import Ġcom . github . jav ap ar ser . symbols olver . resolution . types olver s . ClassLoader Type Solver Ċ import Ġjava . io . Reader Ċ import Ġjava . io . Writer Ċ Ċ class ĠTransformer ( class Loader : ĠClassLoader Ġ= ĠClassLoader . getSystem ClassLoader (). parent ) Ġ{ ĊĠ Ġprivate Ġval Ġparser : ĠJava Parser ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġval Ġsymbol Solver Ġ= ĠJava Symbol Solver ( ĊĠĠĠĠĠĠĠ ĠClassLoader Type Solver ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Loader )) ĊĠĠĠ Ġval Ġconfig Ġ= ĠParser Configuration () ĊĠĠĠ Ġconfig . set Symbol Resolver ( symbol Solver ) ĊĠĠĠ Ġparser Ġ= ĠJava Parser ( config ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThis Ġmethod Ġtransform Ġthe Ġgiven Ġsource Ġcode Ġso Ġthat Ġit Ġdoes Ġnot Ġoccur Ġan Ġunexpected ĊĠĠ Ġ* Ġarithmetic Ġoverflow . ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThe Ġmethod Ġreads Ġthe ĠJava Ġsource Ġcode Ġfrom Ġ[ reader ] Ġand Ġthen Ġwrites Ġout Ġthe Ġtransformed Ġcode ĊĠĠ Ġ* Ġto Ġ[ writer ] Ġwhere Ġall Ġthe Ġarithmetic Ġoperations Ġwhich Ġcould Ġcause Ġan Ġoverflow Ġare Ġreplaced Ġwith ĊĠĠ Ġ* Ġ` xxx Exact ` Ġmethod Ġin Ġ[ Math ] Ġclass , Ġsuch Ġas Ġ[ Math . add Exact ] Ġor Ġ[ Math . subtract Exact ]. ĊĠĠ Ġ* ĊĠĠ Ġ* ĠExample : ĊĠĠ Ġ* Ġ``` ĊĠĠ Ġ* ĠĠ Ġpublic Ġclass ĠMain Ġ{ ĊĠĠ Ġ* ĠĠĠĠ Ġpublic Ġstatic Ġvoid Ġmain ( String [] Ġargs ) Ġ{ ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġint Ġa Ġ= Ġ 1 ; ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġa ++; ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġa Ġ+= Ġ 2 ; ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġint Ġb Ġ= Ġa Ġ- Ġ 3 ; ĊĠĠ Ġ* ĠĠĠĠ Ġ} ĊĠĠ Ġ* ĠĠ Ġ} ĊĠĠ Ġ* Ġ``` ĊĠĠ Ġ* Ġwould Ġbe Ġtransformed Ġto Ġthe Ġbelow Ġcode . ĊĠĠ Ġ* Ġ``` ĊĠĠ Ġ* ĠĠ Ġpublic Ġclass ĠMain Ġ{ ĊĠĠ Ġ* ĠĠĠĠ Ġpublic Ġstatic Ġvoid Ġmain ( String [] Ġargs ) Ġ{ ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġint Ġa Ġ= Ġ 1 ; ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġa Ġ= ĠMath . increment Exact ( a ); ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġa Ġ= ĠMath . add Exact ( a , Ġ 2 ); ĊĠĠ Ġ* ĠĠĠĠĠĠĠ Ġint Ġb Ġ= ĠMath . subtract Exact ( a , Ġ 3 ); ĊĠĠ Ġ* ĠĠĠĠ Ġ} ĊĠĠ Ġ* ĠĠ Ġ} ĊĠĠ Ġ* Ġ``` ĊĠĠ Ġ* ĊĠĠ Ġ* ĠNote Ġthe Ġmethod Ġthrows Ġan Ġ[ Parse Problem Exception ] Ġif Ġthe Ġgiven Ġcode Ġis Ġnot Ġa Ġvalid ĠJava Ġcode . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param [ reader ] Ġthe Ġreader Ġto Ġread Ġthe Ġsource Ġcode Ġfrom Ġto Ġtransform ĊĠĠ Ġ* Ġ@ param [ writer ] Ġthe Ġwriter Ġto Ġwrite Ġthe Ġtransformed Ġcode Ġto ĊĠĠ Ġ*/ ĊĠ Ġfun Ġtransform ( reader : ĠReader , Ġwriter : ĠWriter ) Ġ{ ĊĠĠĠ Ġval Ġcu Ġ= Ġparse ( reader ) ĊĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠ Ġval Ġvisitor Ġ= ĠOverflow able Visitor () ĊĠĠĠĠĠ Ġcu . accept ( visitor , ĠUnit ) ĊĠĠĠ Ġ} Ġwhile Ġ( visitor . re placed ) ĊĊĠĠĠ Ġwriter . write ( cu . toString ()) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġparse ( reader : ĠReader ): ĠCompilation Unit Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= Ġparser . parse ( Parse Start . COMPI L ATION _ UNIT , ĊĠĠĠĠĠĠĠ ĠPro viders . provider ( reader )) ĊĠĠĠ Ġreturn Ġif Ġ( result . is Successful ) Ġ{ ĊĠĠĠĠĠ Ġresult . result . get () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġthrow ĠParse Problem Exception ( result . problems ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ class ĠOverflow able Visitor Ġ: ĠVoid Visitor Adapter < Unit >() Ġ{ ĊĠ Ġprivate Ġval Ġmath Class Ġ= ĠName Expr ( Math :: class . java . simple Name ) ĊĠ Ġvar Ġreplaced Ġ= Ġfalse ĊĊĠ Ġoverride Ġfun Ġvisit ( expr : ĠBinary Expr , Ġarg : ĠUnit ) Ġ{ ĊĠĠĠ Ġsuper . visit ( expr , Ġarg ) ĊĠĠĠ Ġwith ( expr ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( left . is Overflow able () Ġ&& Ġright . is Overflow able () Ġ&& Ġoperator . is Overflow able ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġexpr . replace ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMethod Call Expr ( math Class , Ġoperator . to Math Method (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNode List ( left , Ġright ))) ĊĠĠĠĠĠĠĠ Ġreplaced Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġvisit ( expr : ĠUnary Expr , Ġarg : ĠUnit ) Ġ{ ĊĠĠĠ Ġsuper . visit ( expr , Ġarg ) ĊĠĠĠ Ġexpr . operator . to Math Method ()?. let Ġ{ ĊĠĠĠĠĠ Ġval Ġright Hand Ġ= ĠMethod Call Expr ( math Class , Ġit , ĊĠĠĠĠĠĠĠĠĠ ĠNode List ( expr . expression )) ĊĠĠĠĠĠ Ġexpr . replace ( Assign Expr ( expr . expression , Ġright Hand , ĊĠĠĠĠĠĠĠĠĠ ĠAssign Expr . Operator . ASSIGN )) ĊĠĠĠĠĠ Ġreplaced Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġvisit ( expr : ĠAssign Expr , Ġarg : ĠUnit ) Ġ{ ĊĠĠĠ Ġsuper . visit ( expr , Ġarg ) ĊĠĠĠ Ġwith ( expr ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( target . is Overflow able () Ġ&& Ġvalue . is Overflow able () Ġ&& Ġoperator . is Overflow able ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġright Hand Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMethod Call Expr ( math Class , Ġoperator . to Math Method (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNode List ( target , Ġvalue )) ĊĠĠĠĠĠĠĠ Ġexpr . replace ( Assign Expr ( target , Ġright Hand , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAssign Expr . Operator . ASSIGN )) ĊĠĠĠĠĠĠĠ Ġreplaced Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠBinary Expr . Operator . to Math Method () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠĠĠ ĠBinary Expr . Operator . PLUS Ġ-> ĠMath :: add Exact . name ĊĠĠĠ ĠBinary Expr . Operator . MINUS Ġ-> ĠMath :: subtract Exact . name ĊĠĠĠ ĠBinary Expr . Operator . MULTI PLY Ġ-> ĠMath :: multiply Exact . name ĊĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Unexpected ĠBinary Expr ĠOperator : Ġ$ this ") ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠUnary Expr . Operator . to Math Method () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠĠĠ ĠUnary Expr . Operator . PREFIX _ INCREMENT , ĠUnary Expr . Operator . POST FIX _ INCREMENT Ġ-> ĠMath :: increment Exact . name ĊĠĠĠ ĠUnary Expr . Operator . PREFIX _ DECRE MENT , ĠUnary Expr . Operator . POST FIX _ DECRE MENT Ġ-> ĠMath :: decrement Exact . name ĊĠĠĠ ĠUnary Expr . Operator . MINUS Ġ-> ĠMath :: neg ate Exact . name ĊĠĠĠ Ġelse Ġ-> Ġnull ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠAssign Expr . Operator . to Math Method () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠĠĠ ĠAssign Expr . Operator . PLUS Ġ-> ĠMath :: add Exact . name ĊĠĠĠ ĠAssign Expr . Operator . MINUS Ġ-> ĠMath :: subtract Exact . name ĊĠĠĠ ĠAssign Expr . Operator . MULTI PLY Ġ-> ĠMath :: multiply Exact . name ĊĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Unexpected ĠAssign Expr ĠOperator : Ġ$ this ") ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠExpression . is Overflow able () Ġ= Ġwith ( calculate Resolved Type ()) Ġ{ ĊĠ Ġis Primitive Ġ&& Ġas Primitive (). is Overflow able () Ċ } Ċ Ċ private Ġfun ĠResolved Primitive Type . is Overflow able () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠ ĠResolved Primitive Type . INT , ĠResolved Primitive Type . LONG Ġ-> Ġtrue ĊĠ Ġelse Ġ-> Ġfalse Ċ } Ċ Ċ private Ġfun ĠBinary Expr . Operator . is Overflow able () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠ ĠBinary Expr . Operator . PLUS , ĠBinary Expr . Operator . MINUS , ĠBinary Expr . Operator . MULTI PLY Ġ-> Ġtrue ĊĠ Ġelse Ġ-> Ġfalse Ċ } Ċ Ċ private Ġfun ĠAssign Expr . Operator . is Overflow able () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠ ĠAssign Expr . Operator . PLUS , ĠAssign Expr . Operator . MINUS , ĠAssign Expr . Operator . MULTI PLY Ġ-> Ġtrue ĊĠ Ġelse Ġ-> Ġfalse Ċ }