package Ġcom . j tran sc . plugin . reflection Ċ Ċ import Ġcom . j tran sc . annotation . J Tran sc In visible External Ċ import Ġcom . j tran sc . ast .* Ċ import Ġcom . j tran sc . plugin . J Tran sc Plugin Ċ import Ġcom . j tran sc . reflection . J Tran sc Internal Names Ċ import Ġj . Class Info Ċ import Ġj . Member Info Ċ import Ġj . Program Reflection Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġaims Ġto Ġcreate Ġclasses Ġto Ġperform Ġreflection Ġon Ġavailable Ġclasses Ċ Ġ*/ Ċ class ĠMeta Reflection J Tran sc Plugin Ġ: ĠJ Tran sc Plugin () Ġ{ Ċ ĉ override Ġval Ġpriority : ĠInt Ġ= ĠInt . MAX _ VALUE Ġ- Ġ 1 0 0 0 Ċ ĉ comp anion Ġobject Ġ{ Ċĉ ĉ const Ġval ĠCASE S _ PER _ SWITCH : ĠInt Ġ= Ġ 1 0 0 Ċ ĉ } ĊĊ ĉ fun ĠAst Class . must Reflect ( invisible External Set : ĠSet < String > Ġ= Ġset Of ()): ĠBoolean Ġ{ Ċĉ ĉ return Ġthis . visible Ġ&& Ġ( this . fq name Ġ! in Ġinvisible External Set ) Ġ&& Ġ( this . annotations List . get Native Name For Target ( target Name ) Ġ== Ġnull ) Ċ ĉ } ĊĊ ĉ fun ĠAst Method . must Reflect (): ĠBoolean Ġ= Ġthis . visible ĊĊ ĉ fun ĠAst Field . must Reflect (): ĠBoolean Ġ= Ġthis . visible Ġ&& Ġthis . annotations List . get Remove Field For Target ( target Name ) Ġ== Ġnull ĊĊ ĉ override Ġfun Ġprocess After Tree Sh aking ( program : ĠAst Program ) Ġ{ Ċĉ ĉ // ĠDo Ġnot Ġgenerate Ġif ĠProgram Reflection Ġclass Ġis Ġnot Ġreferenced ! Ċĉ ĉ // ĠAlso Ġmethods Ġare Ġnot Ġupdated Ġin Ġthe Ġcase Ġthey Ġdo Ġnot Ġexist ! Ċĉ ĉ if Ġ( Program Reflection :: class . java . fq name Ġ! in Ġprogram ) Ġreturn Ċĉ ĉ if Ġ( Class Info :: class . java . fq name Ġ! in Ġprogram ) Ġreturn ĊĊĉ ĉ val Ġtypes Ġ= Ġprogram . types Ċĉ ĉ val ĠProgram Reflection Class Ġ= Ġprogram [ Program Reflection :: class . java . fq name ] ĊĊĉ ĉ val Ġannotation Fq name Ġ= Ġ" java . lang . annotation . Annotation ". fq name Ċĉ ĉ val Ġannotation Type Ġ= ĠAst Type . REF ( annotation Fq name ) Ċĉ ĉ val Ġclasses For Annotations Ġ= Ġhash Map Of < Ast Type . REF , ĠAst Class >() ĊĊĉ ĉ fun Ġget Annotation Proxy Class ( annotation Type : ĠAst Type . REF ): ĠAst Class Ġ{ Ċĉĉ ĉ return Ġclasses For Annotations . get Or Put ( annotation Type ) Ġ{ Ċĉĉĉ ĉ val Ġannotation Class Ġ= Ġprogram [ annotation Type ] !! Ċĉĉĉ ĉ val Ġannotation Methods Ġ= Ġannotation Class . methods . filter Ġ{ Ġit . method Type . arg Count Ġ== Ġ 0 Ġ} ĊĊĉĉĉ ĉ val Ġmembers Ġ= Ġannotation Methods . map Ġ{ Ġit . name Ġto Ġit . method Type . ret Ġ} Ċĉĉĉ ĉ val Ġproxy ClassName Ġ= Ġ"${ annotation Type . fq name }\ $ Impl " ĊĊĉĉĉ ĉ val Ġclazz Ġ= Ġprogram . create Data Class ( proxy ClassName . fq name , Ġmembers , Ġinterfaces Ġ= ĠlistOf ( annotation Type . name , Ġannotation Fq name )) Ġ{ Ċĉĉĉĉ ĉ extra Visible Ġ= Ġtrue ĊĊĉĉĉĉ ĉ val Ġannotation Type MR Ġ= ĠAst Method Without Class Ref (" annotation Type ", ĠAst Type . METHOD ( Ast Type . CLASS , ĠlistOf ())) Ċĉĉĉĉ ĉ val ĠgetClass MR Ġ= ĠAst Method Without Class Ref (" getClass ", ĠAst Type . METHOD ( Ast Type . CLASS , ĠlistOf ())) Ċĉĉĉĉ ĉ val ĠtoString MR Ġ= ĠAst Method Without Class Ref (" toString ", ĠAst Type . METHOD ( Ast Type . STRING , ĠlistOf ())) ĊĊĉĉĉĉ ĉ for Ġ( m Ġin Ġannotation Methods ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġref Ġ= ĠAst Method Without Class Ref ( m . name , Ġm . method Type ) Ċĉĉĉĉĉ ĉ if Ġ( ref Ġ== Ġannotation Type MR ) Ġcontinue Ċĉĉĉĉĉ ĉ if Ġ( ref Ġ== ĠgetClass MR ) Ġcontinue Ċĉĉĉĉĉ ĉ if Ġ( ref Ġ== ĠtoString MR ) Ġcontinue Ċĉĉĉĉĉ ĉ create Method ( m . name , Ġm . method Type , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉĉ ĉ extra Visible Ġ= Ġfalse Ċĉĉĉĉĉĉ ĉ RETURN ( THIS [ locate Field ( m . name ) !! ]) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ create Method ( annotation Type MR . name , Ġannotation Type MR . type , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉ ĉ RETURN ( annotation Type . lit ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ create Method ( getClass MR . name , ĠgetClass MR . type , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉ ĉ RETURN ( annotation Type . lit ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ create Method ( toString MR . name , ĠtoString MR . type , Ġasync Opt Ġ= Ġnull ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġappend Object Ġ= ĠAst Method Ref ( StringBuilder :: class . java . fq name , Ġ" append ", ĠAst Type . METHOD ( Ast Type . STRING BUILDER , ĠlistOf ( Ast Type . OBJECT ))) Ċĉĉĉĉĉ ĉ val ĠtoString Ġ= ĠAst Method Ref ( java . lang . Object :: class . java . fq name , Ġ" toString ", ĠAst Type . METHOD ( Ast Type . STRING , ĠlistOf ())) ĊĊĉĉĉĉĉ ĉ var Ġmod : ĠAst Expr Ġ= ĠAst Expr . NEW _ WITH _ CON STRUCTOR ( Ast Method Ref ( Ast Type . STRING BUILDER . name , Ġ"< init >", ĠAst Type . METHOD ( Ast Type . VOID , ĠlistOf ())), ĠlistOf ()) ĊĊĉĉĉĉĉ ĉ var Ġbuffer Ġ= Ġ"" Ċĉĉĉĉĉ ĉ var Ġpos Ġ= Ġ 0 Ċĉĉĉĉĉ ĉ buffer Ġ+= Ġ"@ ${ annotation Type . fq name } (" Ċĉĉĉĉĉ ĉ for Ġ( method Ġin Ġannotation Methods ) Ġ{ Ċĉĉĉĉĉĉ ĉ if Ġ( pos Ġ!= Ġ 0 ) Ġbuffer Ġ+= Ġ"," Ċĉĉĉĉĉĉ ĉ pos ++ Ċĉĉĉĉĉĉ ĉ buffer Ġ+= Ġ"${ method . name } =" Ċĉĉĉĉĉĉ ĉ if Ġ( buffer . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉ ĉ mod Ġ= Ġmod [ append Object ]( buffer . lit ) Ċĉĉĉĉĉĉĉ ĉ buffer Ġ= Ġ"" Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ mod Ġ= Ġmod [ append Object ]( THIS [ method ] (). cast To ( OBJECT )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ mod Ġ= Ġmod [ append Object ](" ) ". lit ) ĊĊĉĉĉĉĉ ĉ RETURN ( mod [ toString ] ()) Ċĉĉĉĉĉ ĉ // RETURN ( Ast Expr . LITERAL ("@ ${ annotation Type . fq name }", Ġtypes )) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ // println (" Created Ġclass : Ġ$ proxy ClassName Ġ: Ġ${ clazz . visible }") ĊĊĉĉĉ ĉ clazz Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ // println (" ---------- ") ĊĊĉ ĉ for Ġ( clazz Ġin Ġprogram . classes . toList (). filter Ġ{ Ġit . extends Or Implements ( annotation Fq name ) Ġ&& Ġ! it . fq name . endsWith ("\ $ Proxy ") Ġ}) Ġ{ Ċĉĉ ĉ // println ("$ clazz : Ġ${ clazz . extends Or Implements ( annotation Fq name )} ") ĊĊĉĉ ĉ getAnnotation Proxy Class ( clazz . ref ) Ċĉ ĉ } ĊĊĉ ĉ val Ġinvisible External Set Ġ= Ġprogram . all Annotations List . getAll Typed < J Tran sc In visible External >(). flatMap Ġ{ Ġit . classes . toList () Ġ}. toSet () ĊĊĉ ĉ val Ġvisible Classes Ġ= Ġprogram . classes . filter Ġ{ Ġit . must Reflect ( invisible External Set ) Ġ} ĊĊĉ ĉ val ĠCLASS _ INFO Ġ= Ġprogram [ Class Info :: class . java . fq name ] Ċĉ ĉ val ĠCLASS _ INFO _ CREATE Ġ= ĠCLASS _ INFO . getMethod Without Overrides ( Class Info :: create . name ) !!. ref ĊĊĉ ĉ val Ġgen Internal ClassNames Ġ= Ġprogram . contains Method ( J Tran sc Internal Names :: class . java . fq name , ĠJ Tran sc Internal Names :: get Internal ClassName . name ) Ċĉ ĉ val Ġgen Internal Member Names Ġ= Ġprogram . contains Method ( J Tran sc Internal Names :: class . java . fq name , ĠJ Tran sc Internal Names :: get Internal FieldName . name ) Ġ|| Ġprogram . contains Method ( J Tran sc Internal Names :: class . java . fq name , ĠJ Tran sc Internal Names :: get Internal MethodName . name ) ĊĊĉ ĉ fun Ġto Annotation Expr ( data : ĠAny ?, Ġtemps : ĠTemp Ast Local Factory , Ġbuilder : ĠAst Builder 2 ): ĠAst Expr Ġ{ Ċĉĉ ĉ return Ġbuilder . run Ġ{ Ċĉĉĉ ĉ when Ġ( data ) Ġ{ Ċĉĉĉĉ ĉ null Ġ-> Ġnull . lit Ċĉĉĉĉ ĉ is ĠAst Annotation Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ if Ġ( data . runtime Visible ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġannotation Type Ġ= Ġprogram [ data . type ] Ċĉĉĉĉĉĉ ĉ val Ġannotation Proxy Ġ= Ġget Annotation Proxy Class ( data . type ) Ċĉĉĉĉĉĉ ĉ val Ġannotation Proxy Constructor Ġ= Ġannotation Proxy . construct ors . first () Ċĉĉĉĉĉĉ ĉ val Ġargs Ġ= Ġarray ListOf < Any ?> () Ċĉĉĉĉĉĉ ĉ for Ġ( m Ġin Ġannotation Type !!. methods ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ val Ġvalue Ġ= Ġdata . elements [ m . name ] Ġ?: Ġm . default Tag Ċĉĉĉĉĉĉĉ ĉ args Ġ+= Ġvalue Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ Ast Expr . NEW _ WITH _ CON STRUCTOR ( annotation Proxy Constructor . ref , Ġargs . map Ġ{ Ġto Annotation Expr ( it , Ġtemps , Ġbuilder ) Ġ}) Ċĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉ ĉ null . lit Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ is ĠAst Field Without Type Ref Ġ-> Ġto Annotation Expr ( program [ data . containing Class ]. locate Field ( data . name ) !!. ref , Ġtemps , Ġbuilder ) Ċĉĉĉĉ ĉ is ĠAst Field Ref Ġ-> ĠAst Expr . FIELD _ STATIC _ ACCESS ( data ) Ċĉĉĉĉ ĉ is ĠPair < *, Ġ*> Ġ-> Ġto Annotation Expr ( data . second , Ġtemps , Ġbuilder ) Ċĉĉĉĉ ĉ is ĠList < *> Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ val Ġlocal Ġ= Ġtemps . create ( ARRAY ( OBJECT )) Ċĉĉĉĉĉ ĉ SET ( local , Ġ( local . type . as Array ()). new Array ( data . size . lit )) Ċĉĉĉĉĉ ĉ for Ġ(( index , Ġitem ) Ġin Ġdata . with Index ()) Ġ{ Ċĉĉĉĉĉĉ ĉ SET _ ARRAY ( local , Ġindex . lit , Ġto Annotation Expr ( item , Ġtemps , Ġbuilder )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ local . expr Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ is Ġcom . j tran sc . org . object web . asm . Type Ġ-> Ġ{ Ċĉĉĉĉĉ ĉ Ast Type . REF ( data . className . fq name ). lit Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ else Ġ-> Ġdata . lit Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ val ĠAN NOT ATION _ ARRAY Ġ= ĠARRAY ( Ast Type . REF (" java . lang . annotation . Annotation ")) ĊĊĉ ĉ Program Reflection Class . getMethod Without Overrides ( Program Reflection :: getClass Annotations . name )?. replace Body Opt Build Ġ{ Ġargs Ġ-> Ċĉĉ ĉ val Ġ( class Id Arg ) Ġ= Ġargs ĊĊĉĉ ĉ val Ġtemps Ġ= ĠTemp Ast Local Factory () ĊĊĉĉ ĉ val Ġclean Visible Classes Ġ= Ġvisible Classes . filter Ġ{ Ġit . runtime Annotations . isNotEmpty () Ġ&& Ġ" java . lang . annotation . Annotation ". fq name Ġ! in Ġit . implement ing Ġ} ĊĊĉĉ ĉ var Ġswitch Index : ĠInt Ġ= Ġ 0 Ċĉĉ ĉ while Ġ( switch Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġclean Visible Classes . size ) Ġ{ Ċĉĉĉ ĉ SWITCH ( class Id Arg . expr ) Ġ{ Ċĉĉĉĉ ĉ var Ġcase Index : ĠInt Ġ= Ġ 0 Ċĉĉĉĉ ĉ while Ġ( case Index Ġ< ĠCASE S _ PER _ SWITCH Ġ&& Ġ( switch Index Ġ* ĠCASE S _ PER _ SWITCH Ġ+ Ġcase Index ) Ġ< Ġclean Visible Classes . size ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġclazz Ġ= Ġclean Visible Classes [ switch Index Ġ* ĠCASE S _ PER _ SWITCH Ġ+ Ġcase Index ] Ċĉĉĉĉĉ ĉ CASE ( clazz . class Id ) Ġ{ Ċĉĉĉĉĉĉ ĉ RETURN ( AN NOT ATION _ ARRAY . new Literal Array ( Ċĉĉĉĉĉĉĉ ĉ clazz . runtime Annotations . map Ġ{ Ġto Annotation Expr ( it , Ġtemps , Ġthis ) Ġ} Ċĉĉĉĉĉĉ ĉ )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ case Index ++ Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ switch Index ++ Ċĉĉ ĉ } Ċĉĉ ĉ RETURN ( NULL ) Ċĉ ĉ } ĊĊĉ ĉ Program Reflection Class . getMethod Without Overrides ( Program Reflection :: getField Annotations . name )?. replace Body Opt Build Ġ{ Ġargs Ġ-> Ċĉĉ ĉ val Ġ( class Id Arg , ĠfieldId Arg ) Ġ= Ġargs ĊĊĉĉ ĉ val Ġtemps Ġ= ĠTemp Ast Local Factory () ĊĊĉĉ ĉ val Ġclean Visible Classes Ġ= Ġvisible Classes . filter Ġ{ Ġit . fields . filter Ġ{ Ġit . must Reflect () Ġ}. flatMap Ġ{ Ġit . runtime Annotations Ġ}. isNotEmpty () Ġ} ĊĊĉĉ ĉ var Ġswitch Index : ĠInt Ġ= Ġ 0 Ċĉĉ ĉ while Ġ( switch Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġclean Visible Classes . size ) Ġ{ Ċĉĉĉ ĉ SWITCH ( class Id Arg . expr ) Ġ{ Ċĉĉĉĉ ĉ var Ġcase Index : ĠInt Ġ= Ġ 0 Ċĉĉĉĉ ĉ while Ġ( case Index Ġ< ĠCASE S _ PER _ SWITCH Ġ&& Ġ( switch Index Ġ Ġ* ĠCASE S _ PER _ SWITCH Ġ+ Ġcase Index ) Ġ< Ġclean Visible Classes . size ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġclazz Ġ= Ġclean Visible Classes [ switch Index Ġ* ĠCASE S _ PER _ SWITCH Ġ+ Ġcase Index ] Ċĉĉĉĉĉ ĉ val Ġfields Ġ= Ġclazz . fields . filter Ġ{ Ġit . must Reflect () Ġ} Ċĉĉĉĉĉ ĉ CASE ( clazz . class Id ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġclass Id Ġ= Ġclazz . class Id Ċĉĉĉĉĉĉ ĉ val Ġper Class Method Ġ= ĠProgram Reflection Class . create Method (" getField Annotations $ class Id ", ĠAst Type . METHOD ( Ast Type . ARRAY ( annotation Type ), ĠAst Type . INT ), Ġis Static Ġ= Ġtrue , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ġargs Ġ-> Ċĉĉĉĉĉĉ ĉ // val Ġper Class Method Ġ= ĠProgram Reflection Class . create Method (" getField Annotations $ class Id ", ĠAst Type . METHOD ( Ast Type . ARRAY ( annotation Type ), ĠAst Type . INT ), Ġis Static Ġ= Ġtrue , Ġasync Opt Ġ= Ġtrue ) Ġ{ Ġargs Ġ-> Ċĉĉĉĉĉĉĉ ĉ val Ġ( fieldId Arg In ) Ġ= Ġargs Ċĉĉĉĉĉĉĉ ĉ SWITCH ( fieldId Arg In . expr ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ for Ġ( field Ġin Ġfields ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ val Ġannotations Ġ= Ġfield . runtime Annotations Ċĉĉĉĉĉĉĉĉĉ ĉ if Ġ( annotations . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ CASE ( field . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( AN NOT ATION _ ARRAY . new Literal Array ( Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ annotations . map Ġ{ Ġto Annotation Expr ( it , Ġtemps , Ġthis ) Ġ} Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ )) Ċĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉĉ ĉ } ĊĊĉĉĉĉĉĉ ĉ RETURN ( per Class Method . invoke ( fieldId Arg . expr )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ case Index ++ Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉĉ ĉ switch Index ++ Ċĉĉ ĉ } Ċĉĉ ĉ RETURN ( NULL ) Ċĉ ĉ } ĊĊĉ ĉ Program Reflection Class . getMethod Without Overrides ( Program Reflection :: getMethod Annotations . name )?. replace Body Opt Build Ġ{ Ġargs Ġ-> Ċĉĉ ĉ val Ġ( class Id Arg , Ġmethod Id Arg ) Ġ= Ġargs ĊĊĉĉ ĉ val Ġtemps Ġ= ĠTemp Ast Local Factory () ĊĊĉĉ ĉ SWITCH ( class Id Arg . expr ) Ġ{ Ċĉĉĉ ĉ for Ġ( clazz Ġin Ġvisible Classes ) Ġ{ Ċĉĉĉĉ ĉ val Ġmethods Ġ= Ġclazz . methods Ċĉĉĉĉ ĉ if Ġ( methods . flatMap Ġ{ Ġit . runtime Annotations Ġ}. isNotEmpty ()) Ġ{ Ċĉĉĉĉĉ ĉ CASE ( clazz . class Id ) Ġ{ Ċĉĉĉĉĉĉ ĉ SWITCH ( method Id Arg . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ for Ġ( method Ġin Ġmethods ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġannotations Ġ= Ġmethod . runtime Annotations Ċĉĉĉĉĉĉĉĉ ĉ if Ġ( annotations . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ CASE ( method . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( AN NOT ATION _ ARRAY . new Literal Array ( Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ annotations . map Ġ{ Ġto Annotation Expr ( it , Ġtemps , Ġthis ) Ġ} Ċĉĉĉĉĉĉĉĉĉĉ ĉ )) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ RETURN ( NULL ) Ċĉ ĉ } ĊĊĉ ĉ Program Reflection Class . getMethod Without Overrides ( Program Reflection :: getMethod Argument Annotations . name )?. replace Body Opt Build Ġ{ Ġargs Ġ-> Ċĉĉ ĉ val Ġ( class Id Arg , Ġmethod Id Arg , Ġarg Index Art ) Ġ= Ġargs ĊĊĉĉ ĉ val Ġtemps Ġ= ĠTemp Ast Local Factory () ĊĊĉĉ ĉ SWITCH ( class Id Arg . expr ) Ġ{ Ċĉĉĉ ĉ for Ġ( clazz Ġin Ġvisible Classes ) Ġ{ Ċĉĉĉĉ ĉ val Ġmethods Ġ= Ġclazz . methods . filter Ġ{ Ġit . must Reflect () Ġ} Ċĉĉĉĉ ĉ if Ġ( methods . flatMap Ġ{ Ġit . parameter Annotations . flatMap Ġ{ Ġit Ġ} Ġ}. isNotEmpty ()) Ġ{ Ċĉĉĉĉĉ ĉ CASE ( clazz . class Id ) Ġ{ Ċĉĉĉĉĉĉ ĉ SWITCH ( method Id Arg . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ for Ġ( method Ġin Ġmethods ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġall Parameter Annotations Ġ= Ġmethod . parameter Annotations . flatMap Ġ{ Ġit Ġ} Ċĉĉĉĉĉĉĉĉ ĉ if Ġ( all Parameter Annotations . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ CASE ( method . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ SWITCH ( arg Index Art . expr ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ for Ġ( arg Index Ġin Ġ 0 Ġuntil Ġmethod . method Type . arg Count ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ val Ġannotations Ġ= Ġmethod . parameter Annotations [ arg Index ] Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ if Ġ( annotations . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉĉĉ ĉ CASE ( arg Index ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( AN NOT ATION _ ARRAY . new Literal Array ( Ċĉĉĉĉĉĉĉĉĉĉĉĉĉĉĉ ĉ annotations . map Ġ{ Ġto Annotation Expr ( it , Ġtemps , Ġthis ) Ġ} Ċĉĉĉĉĉĉĉĉĉĉĉĉĉĉ ĉ )) Ċĉĉĉĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉĉ ĉ RETURN ( NULL ) Ċĉ ĉ } ĊĊĉ ĉ val ĠgetAll Classes Count Method : ĠAst Method ? Ġ= Ġprogram [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes Count . name ) ĊĊĉ ĉ getAll Classes Count Method ?. replace Body Opt Build Ġ{ Ċĉĉ ĉ RETURN ( program . last Class Id . lit ) Ċĉ ĉ } ĊĊĉ ĉ val ĠgetAll Classes Part Methods : ĠList < Ast Method ?> Ġ= ĠlistOf ( Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes 3 0 0 0 . name ), Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes 6 0 0 0 . name ), Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes 9 0 0 0 . name ), Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes 1 2 0 0 0 . name ), Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes 1 5 0 0 0 . name ), Ċĉĉ ĉ program [ Program Reflection . All Classes :: class . java . fq name ]. getMethod Without Overrides ( Program Reflection . All Classes :: getAll Classes Max . name ) Ċĉ ĉ ) ĊĊĉ ĉ for Ġ(( part , ĠgetAll Classes Part Method ) Ġin ĠgetAll Classes Part Methods . with Index ()) Ġ{ Ċĉĉ ĉ getAll Classes Part Method ?. replace Body Opt Build Ġ{ Ċĉĉĉ ĉ val Ġout Ġ= ĠAst Local ( 0 , Ġ" out ", ĠARRAY ( CLASS _ INFO )) Ċĉĉĉ ĉ var Ġpart Visible Classes : ĠList < Ast Class > Ġ= Ġvisible Classes . filter Ġ{ Ġit . class Id Ġin Ġpart * 3 0 0 0 .. (( part + 1 )* 3 0 0 0 - 1 ) Ġ}. sorted By Ġ{ Ġit . class Id Ġ} Ċĉĉĉ ĉ if Ġ( part Ġ== ĠgetAll Classes Part Methods . size Ġ- Ġ 1 ) Ġ{ Ċĉĉĉĉ ĉ part Visible Classes Ġ= Ġ Ġvisible Classes . filter Ġ{ Ġit . class Id Ġ>= Ġ 1 5 0 0 0 Ġ}. sorted By Ġ{ Ġit . class Id Ġ} Ċĉĉĉ ĉ } Ċĉĉĉ ĉ SET ( out , ĠARRAY ( CLASS _ INFO ). new Array ( part Visible Classes . size )) Ċĉĉĉ ĉ for Ġ(( index , Ġold Class ) Ġin Ġpart Visible Classes . with Index ()) Ġ{ Ċĉĉĉĉ ĉ val Ġclass Id Ġ= Ġold Class . class Id Ċĉĉĉĉ ĉ val Ġdirect Interfaces Ġ= Ġold Class . direct Interfaces Ċĉĉĉĉ ĉ val Ġrelated Types Ġ= Ġold Class . getAll Related Types Ids Without 0 At End () Ċĉĉĉĉ ĉ SET _ ARRAY ( out , Ġindex . lit , ĠCLASS _ INFO _ CREATE ( Ċĉĉĉĉĉ ĉ class Id . lit , Ċĉĉĉĉĉ ĉ if Ġ( gen Internal ClassNames ) ĠAst Expr . LITERAL _ REF NAME ( old Class . ref ) Ġelse ĠNULL , Ċĉĉĉĉĉ ĉ old Class . fq name . lit , Ċĉĉĉĉĉ ĉ old Class . modifiers . acc . lit , Ċĉĉĉĉĉ ĉ ( old Class . parent Class ?. class Id Ġ?: Ġ- 1 ). lit , Ċĉĉĉĉĉ ĉ if Ġ( direct Interfaces . isNotEmpty ()) ĠAst Expr . INT ARRAY _ LITERAL ( direct Interfaces . map Ġ{ Ġit . class Id Ġ}) Ġelse Ġnull . lit , Ċĉĉĉĉĉ ĉ if Ġ( related Types . isNotEmpty ()) ĠAst Expr . INT ARRAY _ LITERAL ( related Types ) Ġelse Ġnull . lit Ċĉĉĉĉ ĉ )) Ċĉĉĉ ĉ } Ċĉĉĉ ĉ RETURN ( out . local ) Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĉ ĉ // Ġ@ TODO : ĠWe Ġshould Ġcreate Ġa Ġsub method Ġper Ġclass Ġto Ġavoid Ġcalling Ġ:: SI Ġ( static Ġinitialization ) Ġfor Ġall Ġthe Ġclasses Ċĉ ĉ if Ġ( program . contains ( Program Reflection . Dynamic Invoke :: class . java . fq name )) Ġ{ Ċĉĉ ĉ val Ġdynamic Invoke Class : ĠAst Class Ġ= Ġprogram [ Program Reflection . Dynamic Invoke :: class . java . fq name ] Ċĉĉ ĉ val Ġdynamic Invoke Method : ĠAst Method ? Ġ= Ġdynamic Invoke Class . getMethod Without Overrides ( Program Reflection . Dynamic Invoke :: dynamic Invoke . name ) ĊĊĉĉ ĉ if Ġ( dynamic Invoke Method Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ val Ġadditional Methods : ĠMutable List < Ast Method > Ġ= Ġmutable ListOf () Ċĉĉĉ ĉ val Ġclasses : ĠList < Ast Method > Ġ= Ġvisible Classes . flatMap Ġ{ Ġit . method sWith out Construct ors . filter Ġ{ Ġit . must Reflect () Ġ} Ġ}. sorted By Ġ{ Ġit . id Ġ} ĊĊĉĉĉ ĉ val Ġdynamic Invoke Classes Ġ: List < Ast Class ?> Ġ= ĠlistOf ( Ċĉĉĉĉ ĉ program [ Program Reflection . Dynamic Invoke First :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . Dynamic Invoke Middle :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . Dynamic Invoke Last :: class . java . fq name ] Ċĉĉĉ ĉ ) ĊĊĉĉĉ ĉ var Ġmethod Index : ĠInt Ġ= Ġ 0 Ċĉĉĉ ĉ while Ġ( method Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġclasses . size ) Ġ{ Ċĉĉĉĉ ĉ val Ġm I : ĠInt Ġ= Ġmethod Index Ċĉĉĉĉ ĉ val Ġs I : ĠInt Ġ= Ġmethod Index Ġ* ĠCASE S _ PER _ SWITCH ĊĊĉĉĉĉ ĉ val Ġcurrent Dynamic Invoke Class Ġ= Ġdynamic Invoke Classes [ method Index Ġ% Ġdynamic Invoke Classes . size ] Ċĉĉĉĉ ĉ val Ġcurrent Dynamic Invoke Method : ĠAst Method ? Ġ= Ġcurrent Dynamic Invoke Class !!. getMethod Without Overrides ( Program Reflection . Dynamic Invoke :: dynamic Invoke . name ) Ċĉĉĉĉ ĉ val Ġnew Method : ĠAst Method Ġ= Ċĉĉĉĉĉ ĉ current Dynamic Invoke Class . create Method ( current Dynamic Invoke Method !!. name Ġ+ Ġm I , Ġcurrent Dynamic Invoke Method . method Type , Ġtrue , Ġasync Opt Ġ= Ġtrue ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġ( class Id , Ġmethod Id , Ġobj , Ġargs ) Ġ= Ġit Ċĉĉĉĉĉĉ ĉ var ĠcurrentIndex : ĠInt Ġ= Ġs I Ċĉĉĉĉĉĉ ĉ val Ġfinish Index : ĠInt Ġ= Ġif Ġ( currentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġ< Ġclasses . size ) ĠcurrentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġelse Ġclasses . size ĊĊĉĉĉĉĉĉ ĉ SWITCH ( method Id . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ while Ġ( currentIndex Ġ< Ġfinish Index ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġmethod Ġ= Ġclasses [ currentIndex ] ĊĊĉĉĉĉĉĉĉĉ ĉ val Ġparams : ĠList < Ast Expr > Ġ= Ġmethod . method Type . args . map Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . ARRAY _ ACCESS ( args . expr , Ġit . index . lit ). cast To ( it . type ) Ċĉĉĉĉĉĉĉĉ ĉ } ĊĊĉĉĉĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= Ġif Ġ( method . is Static ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . CALL _ STATIC ( method . containing Class . ref , Ġmethod . ref , Ġparams ) Ċĉĉĉĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . CALL _ INSTANCE ( obj . expr . cast To ( method . containing Class . ref ), Ġmethod . ref , Ġparams ) Ċĉĉĉĉĉĉĉĉ ĉ } ĊĊĉĉĉĉĉĉĉĉ ĉ CASE ( method . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ if Ġ( method . method Type . ret Void ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ STM ( call Expr Un cast ed ) Ċĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( OBJECT )) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ currentIndex ++ Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ additional Methods . add ( new Method ) Ċĉĉĉĉ ĉ method Index ++ Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ dynamic Invoke Method . replace Body Opt Build Ġ{ Ċĉĉĉĉ ĉ val Ġ( class Id , Ġmethod Id , Ġobj , Ġargs ) Ġ= Ġit Ċĉĉĉĉ ĉ var Ġid : ĠInt Ġ= Ġadditional Methods . size ĊĊĉĉĉĉ ĉ while Ġ(-- id Ġ>= Ġ 0 ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġmethod : ĠAst Method Ġ= Ġadditional Methods [ id ] Ċĉĉĉĉĉ ĉ val Ġconstructor : ĠAst Method Ġ= Ġclasses [ id Ġ* ĠCASE S _ PER _ SWITCH ] Ċĉĉĉĉĉ ĉ IF ( Ast Expr . BIN OP ( Ast Type . BOOL , Ġmethod Id . expr , ĠAst Bin op . GE , Ġconstructor . id . lit )) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġparams : ĠList < Ast Expr > Ġ= ĠlistOf ( class Id . expr , Ġmethod Id . expr , Ġobj . expr , Ġargs . expr ) Ċĉĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= ĠAst Expr . CALL _ STATIC ( method . ref , Ġparams ) Ċĉĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( OBJECT )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĊĉ ĉ // Ġ@ TODO : ĠWe Ġshould Ġcreate Ġa Ġsub method Ġper Ġclass Ġto Ġavoid Ġcalling Ġ:: SI Ġ( static Ġinitialization ) Ġfor Ġall Ġthe Ġclasses Ċĉ ĉ if Ġ( program . contains ( Program Reflection . Dynamic New :: class . java . fq name )) Ġ{ Ċĉĉ ĉ val Ġdynamic New Class : ĠAst Class Ġ= Ġprogram [ Program Reflection . Dynamic New :: class . java . fq name ] Ċĉĉ ĉ val Ġdynamic New Method : ĠAst Method ? Ġ= Ġdynamic New Class . getMethod Without Overrides ( Program Reflection . Dynamic New :: dynamic New . name ) ĊĊĉĉ ĉ if Ġ( dynamic New Method Ġ!= Ġnull ) Ġ{ Ċĉĉĉ ĉ val Ġadditional Methods : ĠMutable List < Ast Method > Ġ= Ġmutable ListOf () Ċĉĉĉ ĉ val Ġclasses : ĠList < Ast Method > Ġ= Ġvisible Classes . filter Ġ{ Ġ! it . is Abstract Ġ&& Ġ! it . is Interface Ġ}. flatMap Ġ{ Ġit . construct ors . filter Ġ{ Ġit . must Reflect () Ġ} Ġ}. sorted By Ġ{ Ġit . id Ġ} ĊĊĉĉĉ ĉ var Ġmethod Index : ĠInt Ġ= Ġ 0 Ċĉĉĉ ĉ while Ġ( method Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġclasses . size ) Ġ{ Ċĉĉĉĉ ĉ val Ġm I : ĠInt Ġ= Ġmethod Index Ċĉĉĉĉ ĉ val Ġs I : ĠInt Ġ= Ġmethod Index Ġ* ĠCASE S _ PER _ SWITCH ĊĊĉĉĉĉ ĉ val Ġnew Method : ĠAst Method Ġ= Ċĉĉĉĉĉ ĉ dynamic New Class . create Method ( dynamic New Method . name Ġ+ Ġm I , Ġdynamic New Method . method Type , Ġtrue , Ġasync Opt Ġ= Ġtrue ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġ( class Id , Ġmethod Id , Ġargs ) Ġ= Ġit Ċĉĉĉĉĉĉ ĉ var ĠcurrentIndex : ĠInt Ġ= Ġs I Ċĉĉĉĉĉĉ ĉ val Ġfinish Index : ĠInt Ġ= Ġif Ġ( currentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġ< Ġclasses . size ) ĠcurrentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġelse Ġclasses . size ĊĊĉĉĉĉĉĉ ĉ SWITCH ( method Id . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ while Ġ( currentIndex Ġ< Ġfinish Index ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġconstructor Ġ= Ġclasses [ currentIndex ] ĊĊĉĉĉĉĉĉĉĉ ĉ CASE ( constructor . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ val Ġparams Ġ= Ġconstructor . method Type . args . map Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . ARRAY _ ACCESS ( args . expr , Ġit . index . lit ). cast To ( it . type ) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċ Ċĉĉĉĉĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= ĠAst Expr . NEW _ WITH _ CON STRUCTOR ( constructor . ref , Ġparams ) Ċ Ċĉĉĉĉĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( OBJECT )) Ċĉĉĉĉĉĉĉĉ ĉ } ĊĊĉĉĉĉĉĉĉĉ ĉ currentIndex ++ Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ additional Methods . add ( new Method ) Ċĉĉĉĉ ĉ method Index ++ Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ dynamic New Method . replace Body Opt Build Ġ{ Ċĉĉĉĉ ĉ val Ġ( class Id , Ġmethod Id , Ġargs ) Ġ= Ġit Ċĉĉĉĉ ĉ var Ġid : ĠInt Ġ= Ġadditional Methods . size ĊĊĉĉĉĉ ĉ while Ġ(-- id Ġ>= Ġ 0 ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġmethod : ĠAst Method Ġ= Ġadditional Methods [ id ] Ċĉĉĉĉĉ ĉ val Ġconstructor : ĠAst Method Ġ= Ġclasses [ id Ġ* ĠCASE S _ PER _ SWITCH ] Ċĉĉĉĉĉ ĉ IF ( Ast Expr . BIN OP ( Ast Type . BOOL , Ġmethod Id . expr , ĠAst Bin op . GE , Ġconstructor . id . lit )) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġparams : ĠList < Ast Expr > Ġ= ĠlistOf ( class Id . expr , Ġmethod Id . expr , Ġargs . expr ) Ċĉĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= ĠAst Expr . CALL _ STATIC ( method . ref , Ġparams ) Ċĉĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( OBJECT )) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } ĊĊĊĉ ĉ // ĠMember Ġinformation Ġ( construct ors , Ġmethods Ġand Ġfields ) Ċĉ ĉ if Ġ( Member Info :: class . java . fq name Ġin Ġprogram ) Ġ{ Ċĉĉ ĉ val ĠMember Info Class Ġ= Ġprogram [ Member Info :: class . java . fq name ] Ċĉĉ ĉ val ĠMember Info _ create Ġ= ĠMember Info Class . getMethod Without Overrides ( Member Info :: create . name ) !!. ref ĊĊĉĉ ĉ data Ġclass ĠMember Info With Ref ( val Ġref : ĠAny , Ġval Ġmi : ĠMember Info ) ĊĊĉĉ ĉ fun ĠAst Builder 2 . gen Member List ( args : ĠList < Ast Argument >, Ġlist : ĠList < Pair < Ast Class , ĠList < Member Info With Ref >> >, Ġadditional Methods : ĠList < Ast Method >) Ġ{ Ċĉĉĉ ĉ val Ġ( class Id Arg ) Ġ= Ġargs Ċĉĉĉ ĉ var Ġid : ĠInt Ġ= Ġadditional Methods . size ĊĊĉĉĉ ĉ while Ġ(-- id Ġ>= Ġ 0 ) Ġ{ Ċĉĉĉĉ ĉ val Ġmethod : ĠAst Method Ġ= Ġadditional Methods [ id ] Ċĉĉĉĉ ĉ val Ġ( key Class , Ġmembers ) Ġ= Ġlist [ id Ġ* ĠCASE S _ PER _ SWITCH ] Ċĉĉĉĉ ĉ IF ( Ast Expr . BIN OP ( Ast Type . BOOL , Ġclass Id Arg . expr , ĠAst Bin op . GE , Ġkey Class . class Id . lit )) Ġ{ Ċĉĉĉĉĉ ĉ val Ġparams Ġ= ĠlistOf ( class Id Arg . expr ) Ċĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= ĠAst Expr . CALL _ STATIC ( method . ref , Ġparams ) ĊĊĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( ARRAY ( Member Info Class ))) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ RETURN ( NULL ) Ċĉĉ ĉ } ĊĊĉĉ ĉ fun Ġgen Member Methods ( list : ĠList < Pair < Ast Class , ĠList < Member Info With Ref >> >, Ġclasses : ĠList < Ast Class >, ĠmethodName : ĠString , Ġgeneral Class : ĠAst Class ) Ġ{ ĊĊĉĉĉ ĉ val Ġadditional Methods : ĠMutable List < Ast Method > Ġ= Ġmutable ListOf () Ċĉĉĉ ĉ var Ġmethod Index : ĠInt Ġ= Ġ 0 Ċĉĉĉ ĉ while Ġ( method Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġlist . size ) Ġ{ Ċĉĉĉĉ ĉ val Ġm I : ĠInt Ġ= Ġmethod Index Ċĉĉĉĉ ĉ val Ġs I : ĠInt Ġ= Ġmethod Index Ġ* ĠCASE S _ PER _ SWITCH Ċĉĉĉĉ ĉ val Ġparent Class : ĠAst Class Ġ= Ġclasses [ method Index Ġ% Ġclasses . size ] Ċĉĉĉĉ ĉ val Ġparent Method : ĠAst Method ? Ġ= Ġparent Class . getMethod Without Overrides ( methodName ) ĊĊĉĉĉĉ ĉ val Ġnew Method : ĠAst Method Ġ= Ċĉĉĉĉĉ ĉ parent Class . create Method ( parent Method !!. name Ġ+ Ġm I , Ġparent Method . method Type , Ġtrue , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġ( class Id Arg ) Ġ= Ġit Ċĉĉĉĉĉĉ ĉ val Ġout Ġ= ĠAst Local ( 0 , Ġ" out ", ĠARRAY ( Member Info Class )) ĊĊĉĉĉĉĉĉ ĉ var ĠcurrentIndex : ĠInt Ġ= Ġs I Ċĉĉĉĉĉĉ ĉ val Ġfinish Index : ĠInt Ġ= Ġif Ġ( currentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġ< Ġlist . size ) ĠcurrentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġelse Ġlist . size ĊĊĉĉĉĉĉĉ ĉ SWITCH ( class Id Arg . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ while Ġ( currentIndex Ġ< Ġfinish Index ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġ( key Class , Ġmembers ) Ġ= Ġlist [ currentIndex ] Ċĉĉĉĉĉĉĉĉ ĉ if Ġ( members . isNotEmpty ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ CASE ( key Class . class Id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ SET ( out , ĠARRAY ( Member Info Class ). new Array ( members . size . lit )) Ċ Ċĉĉĉĉĉĉĉĉĉĉ ĉ for Ġ(( index , Ġmember With Ref ) Ġin Ġmembers . with Index ()) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ val Ġref Ġ= Ġmember With Ref . ref Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ val Ġmember Ġ= Ġmember With Ref . mi Ċ Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ SET _ ARRAY ( out , Ġindex . lit , ĠMember Info _ create ( Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ member . id . lit , Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ if Ġ( gen Internal Member Names ) ĠAst Expr . LITERAL _ REF NAME ( ref ) Ġelse ĠNULL , Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ member . name . lit , Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ member . modifiers . lit , Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ member . desc . lit , Ċĉĉĉĉĉĉĉĉĉĉĉĉ ĉ member . generic Desc . lit Ċĉĉĉĉĉĉĉĉĉĉĉ ĉ )) Ċĉĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉĉ ĉ RETURN ( out . local ) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ currentIndex ++ Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ additional Methods . add ( new Method ) Ċĉĉĉĉ ĉ method Index ++ Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ general Class . getMethod Without Overrides ( methodName ) !!. replace Body Opt Build Ġ{ Ċĉĉĉĉ ĉ gen Member List ( it , Ġlist , Ġadditional Methods ) Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĉĉ ĉ // ĠProgram Reflection Class . get Construct ors Ċĉĉ ĉ if Ġ( program . contains ( Program Reflection . All Construct ors :: class . java . fq name )) Ġ{ Ċĉĉĉ ĉ val Ġlist : ĠList < Pair < Ast Class , ĠList < Member Info With Ref >>> Ġ= Ġvisible Classes . map Ġ{ Ċĉĉĉĉ ĉ it Ġto Ġit . construct ors . filter Ġ{ Ġit . must Reflect () Ġ}. map Ġ{ Ċĉĉĉĉĉ ĉ Member Info With Ref ( it . ref , ĠMember Info ( it . id , Ġnull , Ġit . name , Ġit . modifiers . acc , Ġit . desc , Ġit . generic Signature )) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ }. toList () Ċĉĉĉ ĉ val Ġall Construct ors Classes Ġ: List < Ast Class > Ġ= ĠlistOf ( Ċĉĉĉĉ ĉ program [ Program Reflection . All Construct ors First :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Construct ors Middle :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Construct ors Last :: class . java . fq name ] Ċĉĉĉ ĉ ) Ċĉĉĉ ĉ gen Member Methods ( list , Ġall Construct ors Classes , ĠProgram Reflection . All Construct ors :: get Construct ors . name , Ġprogram [ Program Reflection . All Construct ors :: class . java . fq name ]) Ċĉĉ ĉ } ĊĊĉĉ ĉ // ĠProgram Reflection Class . get Methods Ċĉĉ ĉ if Ġ( program . contains ( Program Reflection . All Methods :: class . java . fq name )) Ġ{ Ċĉĉĉ ĉ val Ġlist : ĠList < Pair < Ast Class , ĠList < Member Info With Ref >>> Ġ= Ġvisible Classes . map Ġ{ Ċĉĉĉĉ ĉ it Ġto Ġit . method sWith out Construct ors . filter Ġ{ Ġit . must Reflect () Ġ}. map Ġ{ Ċĉĉĉĉĉ ĉ Member Info With Ref ( it . ref , ĠMember Info ( it . id , Ġnull , Ġit . name , Ġit . modifiers . acc , Ġit . desc , Ġit . generic Signature )) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ }. toList () Ċĉĉĉ ĉ val Ġall Methods Classes Ġ: List < Ast Class > Ġ= ĠlistOf ( Ċĉĉĉĉ ĉ program [ Program Reflection . All Methods First :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Methods Middle :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Methods Last :: class . java . fq name ] Ċĉĉĉ ĉ ) Ċĉĉĉ ĉ gen Member Methods ( list , Ġall Methods Classes , ĠProgram Reflection . All Methods :: get Methods . name , Ġprogram [ Program Reflection . All Methods :: class . java . fq name ]) Ċĉĉ ĉ } ĊĊĉĉ ĉ // ĠProgram Reflection Class . get Fields Ċĉĉ ĉ if Ġ( program . contains ( Program Reflection . All Fields :: class . java . fq name )) Ġ{ Ċĉĉĉ ĉ val Ġlist : ĠList < Pair < Ast Class , ĠList < Member Info With Ref >>> Ġ= Ġvisible Classes . map Ġ{ Ċĉĉĉĉ ĉ it Ġto Ġit . fields . filter Ġ{ Ġit . must Reflect () Ġ}. map Ġ{ Ċĉĉĉĉĉ ĉ Member Info With Ref ( it . ref , ĠMember Info ( it . id , Ġnull , Ġit . name , Ġit . modifiers . acc , Ġit . desc , Ġit . generic Signature )) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ }. toList () Ċĉĉĉ ĉ val Ġall Fields Classes Ġ: List < Ast Class > Ġ= ĠlistOf ( Ċĉĉĉĉ ĉ program [ Program Reflection . All Fields First :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Fields Middle :: class . java . fq name ], Ċĉĉĉĉ ĉ program [ Program Reflection . All Fields Last :: class . java . fq name ] Ċĉĉĉ ĉ ) Ċĉĉĉ ĉ gen Member Methods ( list , Ġall Fields Classes , ĠProgram Reflection . All Fields :: get Fields . name , Ġprogram [ Program Reflection . All Fields :: class . java . fq name ]) Ċĉĉ ĉ } ĊĊĉĉ ĉ // ĠProgram Reflection Class . dynamic Get Ċĉĉ ĉ if Ġ( program . contains ( Program Reflection . Dynamic Get :: class . java . fq name )) Ġ{ Ċĉĉĉ ĉ val Ġdynamic GetClass : ĠAst Class Ġ= Ġprogram [ Program Reflection . Dynamic Get :: class . java . fq name ] Ċĉĉĉ ĉ val Ġdynamic GetMethod : ĠAst Method ? Ġ= Ġdynamic GetClass . getMethod Without Overrides ( Program Reflection . Dynamic Get :: dynamic Get . name ) ĊĊĉĉĉ ĉ if Ġ( dynamic GetMethod Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉ ĉ val Ġadditional Methods : ĠMutable List < Ast Method > Ġ= Ġmutable ListOf () Ċĉĉĉĉ ĉ val Ġfields : ĠList < Ast Field > Ġ= Ġvisible Classes . flatMap Ġ{ Ġit . fields . filter Ġ{ Ġit . must Reflect () Ġ} Ġ}. sorted By Ġ{ Ġit . id Ġ} ĊĊĉĉĉĉ ĉ var Ġmethod Index : ĠInt Ġ= Ġ 0 Ċĉĉĉĉ ĉ while Ġ( method Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġfields . size ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġm I : ĠInt Ġ= Ġmethod Index Ċĉĉĉĉĉ ĉ val Ġs I : ĠInt Ġ= Ġmethod Index Ġ* ĠCASE S _ PER _ SWITCH ĊĊĉĉĉĉĉ ĉ val Ġnew Method : ĠAst Method Ġ= Ġdynamic GetClass . create Method ( dynamic GetMethod . name Ġ+ Ġm I , Ġdynamic GetMethod . method Type , Ġtrue , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġ( class Id , ĠfieldId , Ġobj Param ) Ġ= Ġit Ċĉĉĉĉĉĉ ĉ var ĠcurrentIndex : ĠInt Ġ= Ġs I Ċĉĉĉĉĉĉ ĉ val Ġfinish Index : ĠInt Ġ= Ġif Ġ( currentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġ< Ġfields . size ) ĠcurrentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġelse Ġfields . size ĊĊĉĉĉĉĉĉ ĉ SWITCH ( fieldId . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ while Ġ( currentIndex Ġ< Ġfinish Index ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġfield Ġ= Ġfields [ currentIndex ] ĊĊĉĉĉĉĉĉĉĉ ĉ val Ġexpr Ġ= Ġif Ġ( field . is Static ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . FIELD _ STATIC _ ACCESS ( field . ref ) Ċĉĉĉĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ Ast Expr . FIELD _ INSTANCE _ ACCESS ( field . ref , Ġobj Param . expr . cast To ( field . containing Class . ast Type )) Ċĉĉĉĉĉĉĉĉ ĉ } ĊĊĉĉĉĉĉĉĉĉ ĉ CASE ( field . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ RETURN ( expr . cast To ( OBJECT )) Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ currentIndex ++ Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ additional Methods . add ( new Method ) Ċĉĉĉĉĉ ĉ method Index ++ Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ dynamic GetMethod . replace Body Opt Build Ġ{ Ċĉĉĉĉĉ ĉ val Ġ( class Id , ĠfieldId , Ġobj Param ) Ġ= Ġit Ċĉĉĉĉĉ ĉ var Ġid : ĠInt Ġ= Ġadditional Methods . size ĊĊĉĉĉĉĉ ĉ while Ġ(-- id Ġ>= Ġ 0 ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġmethod : ĠAst Method Ġ= Ġadditional Methods [ id ] Ċĉĉĉĉĉĉ ĉ val Ġfield : ĠAst Field Ġ= Ġfields [ id Ġ* ĠCASE S _ PER _ SWITCH ] Ċĉĉĉĉĉĉ ĉ IF ( Ast Expr . BIN OP ( Ast Type . BOOL , ĠfieldId . expr , ĠAst Bin op . GE , Ġfield . id . lit )) Ġ{ Ċĉĉĉĉĉĉĉ ĉ val Ġparams Ġ= ĠlistOf ( class Id . expr , ĠfieldId . expr , Ġobj Param . expr ) Ċĉĉĉĉĉĉĉ ĉ val Ġcall Expr Un cast ed Ġ= ĠAst Expr . CALL _ STATIC ( method . ref , Ġparams ) Ċĉĉĉĉĉĉĉ ĉ RETURN ( call Expr Un cast ed . cast To ( OBJECT )) Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ RETURN ( NULL ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊĊĉĉ ĉ // ĠProgram Reflection Class . dynamic Set Ċĉĉ ĉ if Ġ( program . contains ( Program Reflection . Dynamic Set :: class . java . fq name )) Ġ{ Ċĉĉĉ ĉ val Ġdynamic Set Class : ĠAst Class Ġ= Ġprogram [ Program Reflection . Dynamic Set :: class . java . fq name ] Ċĉĉĉ ĉ val Ġdynamic Set Method : ĠAst Method ? Ġ= Ġdynamic Set Class . getMethod Without Overrides ( Program Reflection . Dynamic Set :: dynamic Set . name ) ĊĊĉĉĉ ĉ if Ġ( dynamic Set Method Ġ!= Ġnull ) Ġ{ Ċĉĉĉĉ ĉ val Ġadditional Methods : ĠMutable List < Ast Method > Ġ= Ġmutable ListOf () Ċĉĉĉĉ ĉ val Ġfields : ĠList < Ast Field > Ġ= Ġvisible Classes . flatMap Ġ{ Ġit . fields . filter Ġ{ Ġit . must Reflect () Ġ} Ġ}. sorted By Ġ{ Ġit . id Ġ} ĊĊĉĉĉĉ ĉ var Ġmethod Index : ĠInt Ġ= Ġ 0 Ċĉĉĉĉ ĉ while Ġ( method Index Ġ* ĠCASE S _ PER _ SWITCH Ġ< Ġfields . size ) Ġ{ Ċĉĉĉĉĉ ĉ val Ġm I : ĠInt Ġ= Ġmethod Index Ċĉĉĉĉĉ ĉ val Ġs I : ĠInt Ġ= Ġmethod Index Ġ* ĠCASE S _ PER _ SWITCH ĊĊĉĉĉĉĉ ĉ val Ġnew Method : ĠAst Method Ġ= Ġdynamic Set Class . create Method ( dynamic Set Method . name Ġ+ Ġm I , Ġdynamic Set Method . method Type , Ġtrue , Ġasync Opt Ġ= Ġfalse ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġ( class Id Param , ĠfieldId Param , Ġobj Param , Ġvalue Param ) Ġ= Ġit Ċĉĉĉĉĉĉ ĉ var ĠcurrentIndex : ĠInt Ġ= Ġs I Ċĉĉĉĉĉĉ ĉ val Ġfinish Index : ĠInt Ġ= Ġif Ġ( currentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġ< Ġfields . size ) ĠcurrentIndex Ġ+ ĠCASE S _ PER _ SWITCH Ġelse Ġfields . size ĊĊĉĉĉĉĉĉ ĉ SWITCH ( fieldId Param . expr ) Ġ{ Ċĉĉĉĉĉĉĉ ĉ while Ġ( currentIndex Ġ< Ġfinish Index ) Ġ{ Ċĉĉĉĉĉĉĉĉ ĉ val Ġfield Ġ= Ġfields [ currentIndex ] Ċĉĉĉĉĉĉĉĉ ĉ val Ġexpr Ġ= Ġvalue Param . expr . cast To ( field . type ) Ċĉĉĉĉĉĉĉĉ ĉ CASE ( field . id ) Ġ{ Ċĉĉĉĉĉĉĉĉĉ ĉ if Ġ( field . is Static ) Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ STM ( Ast St m . SET _ FIELD _ STATIC ( field . ref , Ġexpr )) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ġelse Ġ{ Ċĉĉĉĉĉĉĉĉĉĉ ĉ STM ( Ast St m . SET _ FIELD _ INSTANCE ( field . ref , Ġobj Param . expr . cast To ( field . containing Class . ast Type ), Ġexpr )) Ċĉĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉĉ ĉ Ast St m . BREAK () Ċĉĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉĉĉ ĉ currentIndex ++ Ċĉĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ additional Methods . add ( new Method ) Ċĉĉĉĉĉ ĉ method Index ++ Ċĉĉĉĉ ĉ } ĊĊĉĉĉĉ ĉ dynamic Set Method . replace Body Opt Build Ġ{ Ċĉĉĉĉĉ ĉ val Ġ( class Id Param , ĠfieldId Param , Ġobj Param , Ġvalue Param ) Ġ= Ġit Ċĉĉĉĉĉ ĉ var Ġid : ĠInt Ġ= Ġadditional Methods . size ĊĊĉĉĉĉĉ ĉ while Ġ(-- id Ġ>= Ġ 0 ) Ġ{ Ċĉĉĉĉĉĉ ĉ val Ġmethod : ĠAst Method Ġ= Ġadditional Methods [ id ] Ċĉĉĉĉĉĉ ĉ val Ġfield : ĠAst Field Ġ= Ġfields [ id Ġ* ĠCASE S _ PER _ SWITCH ] Ċĉĉĉĉĉĉ ĉ IF ( Ast Expr . BIN OP ( Ast Type . BOOL , ĠfieldId Param . expr , ĠAst Bin op . GE , Ġfield . id . lit )) Ġ{ Ċĉĉĉĉĉĉĉ ĉ val Ġparams Ġ= ĠlistOf ( class Id Param . expr , ĠfieldId Param . expr , Ġobj Param . expr , Ġvalue Param . expr ) Ċĉĉĉĉĉĉĉ ĉ STM ( Ast Expr . CALL _ STATIC ( method . ref , Ġparams )) Ċĉĉĉĉĉĉĉ ĉ RETURN () Ċĉĉĉĉĉĉ ĉ } Ċĉĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } Ċĉĉ ĉ } Ċĉ ĉ } Ċ ĉ } Ċ } ĊĊ