/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 . android . gradle . replic ator . codegen Ċ Ċ import Ġjava . lang . reflect . Modifier Ċ import Ġkotlin . random . Random Ċ import Ġkotlin . reflect .* Ċ import Ġkotlin . reflect . full . create Type Ċ import Ġkotlin . reflect . full . declared Member Functions Ċ import Ġkotlin . reflect . full . primary Constructor Ċ import Ġkotlin . reflect . jvm . jvm Er asure Ċ import Ġkotlin . reflect . jvm . kotlin Function Ċ Ċ class ĠSingle ClassGenerator ( ĊĠĠĠĠĠĠĠ Ġgenerator : ĠClass Generator , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġparams : ĠClass Generation Parameters , ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠpackageName : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠclassName : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġapi Class Picker : ĠImport Class Picker , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġimpl Class Picker : ĠImport Class Picker , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġrandom : ĠRandom Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġclass Generator Ġ= ĠModel Builder ClassGenerator ( generator ) ĊĊĠĠĠ Ġprivate Ġvar Ġcurrent Block Depth : ĠInt Ġ= Ġ 0 ; ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerate Ġa Ġsingle Ġclass Ġusing Ġthe Ġprovided Ġgeneration Ġparameters . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgenerate () Ġ{ ĊĠĠĠĠĠĠĠ Ġclass Generator . define Class ( packageName , ĠclassName ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . max NumberOf Instance Vars Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. random . nextInt ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . min NumberOf Instance Vars , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . max NumberOf Instance Vars ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Instance Variable () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . max NumberOf Methods Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. random . nextInt ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . min NumberOf Methods , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . max NumberOf Methods ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Method () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Method () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgenerate Ġparameters . ĊĠĠĠĠĠĠĠ Ġval Ġparameters Ġ= Ġmutable ListOf < Param Model >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 .. random . nextInt ( 0 , Ġparams . max NumberOf Method Parameters )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameter Type Ġ= Ġfind Suit able Type ( api Class Picker ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParam Model ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" param $ j ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġclass Generator . declare Method (" method ", Ġparameters , Ġnull , Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( block Number Ġin Ġparams . min NumberOf Methods .. random . nextInt ( params . max NumberOf Method Blocks )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Block () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Block () Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Block Depth ++ ĊĠĠĠĠĠĠĠ Ġif Ġ( current Block Depth Ġ> Ġparams . max Method Depth ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd MethodCall () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( random . nextInt ( 1 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 .. 1 Ġ-> Ġadd Loop Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 2 .. 6 Ġ-> Ġadd MethodCall () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 7 Ġ-> Ġadd Lambda () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 8 .. 9 Ġ-> Ġadd If Statement () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġprintln (" No Ġstatement Ġ! ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Loop Block () Ġ{ ĊĠĠĠĠĠĠĠ Ġclass Generator . loop Block (" i ", Ġrandom . nextInt ( 7 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . max NumberOf Blocks In Loop Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 .. Random . nextInt ( params . max NumberOf Blocks In Loop )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Instance Variable (): ĠK Class < *> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġreceiver Type Ġ= Ġfind Suit able Type ( api Class Picker ) ĊĊĠĠĠĠĠĠĠ Ġclass Generator . declare Variable ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠField Model (" instance _ var ", Ġreceiver Type , Ġfalse , ĠModifier . PRIVATE ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . allocate Value ( random , Ġfalse , Ġreceiver Type )) ĊĠĠĠĠĠĠĠ Ġreturn Ġreceiver Type . type ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd MethodCall () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( random . nextInt ( 1 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 0 .. 6 Ġ-> Ġadd Local Variable And MethodCall () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Ġ 7 .. 9 Ġ-> Ġadd Function Parameter MethodCall () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġprintln (" No Ġstatement Ġ! ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Local Variable And MethodCall () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġalloc atable Type Ġ= Ġfind Suit able Type ( impl Class Picker ) ĊĠĠĠĠĠĠĠ Ġval Ġvariable Name Ġ= Ġclass Generator . declare Variable ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠField Model (" local _ var ", Ġalloc atable Type , Ġfalse ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . allocate Value ( random , Ġfalse , Ġalloc atable Type ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġclass Generator . indent () ĊĠĠĠĠĠĠĠ Ġif Ġ( alloc atable Type . callable Methods . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd MethodCall ( variable Name , Ġalloc atable Type . callable Methods . random ( random )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġclass Generator . println () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInformation Ġabout Ġa Ġmethod Ġcall , Ġthe Ġvariable Ġcontaining Ġthe Ġinstance Ġto Ġbe Ġinvoked , Ġand Ġthe Ġmethod Ġto Ġinvoke . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġclass ĠMethod Call ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvariable : ĠField Model , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod : ĠK Function < *> ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġadd Function Parameter MethodCall () Ġ{ ĊĠĠĠĠĠĠĠ Ġclass Generator . getLocal Variables (). forEach Ġ{ Ġparam Model Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( param Model . class Model . type . simple Name ?. contains (" String ") Ġ== Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind Suit able Method To Call ( param Model . class Model . type . declared Member Functions )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . indent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd MethodCall ( param Model , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . println () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ addFunction Parameter MethodCall ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd MethodCall ( receiver : ĠField Model , Ġmethod : ĠK Function <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Inline MethodCall ( receiver , Ġmethod ) ĊĠĠĠĠĠĠĠ Ġclass Generator . add Line Delimiter () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Inline MethodCall ( receiver : ĠField Model , Ġmethod : ĠK Function <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparameters Values Ġ= Ġmethod . parameters . filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . kind Ġ== ĠK Parameter . Kind . VALUE ĊĠĠĠĠĠĠĠ Ġ}. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . allocate Value ( random , Ġit . is Var arg , Ġit . type . jvm Er asure . to Type Model ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġclass Generator . call Function ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceiver , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters Values ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd If Statement () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmethod To Call Ġ= Ġfind Method Return ing ( Boolean :: class . create Type ()) ĊĠĠĠĠĠĠĠ Ġval Ġshould Generate Else Block Ġ= Ġrandom . next Boolean () ĊĠĠĠĠĠĠĠ Ġval Ġblock Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . max NumberOf Blocks In If Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( statement Index Ġin Ġ 0 .. random . nextInt ( params . max NumberOf Blocks In If Ġ- Ġ 1 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġelse Block : Ġ(() Ġ-> ĠUnit )? Ġ= Ġif Ġ( should Generate Else Block Ġ&& Ġparams . max NumberOf Blocks In If Else Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( statement Index Ġin Ġ 0 .. random . nextInt ( params . max NumberOf Blocks In If Else Ġ- Ġ 1 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( method To Call Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġallocated Value Ġ= Ġclass Generator . allocate Value ( random , Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClass Model ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠObject :: class , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠObject :: class . primary Constructor !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . if Block ({ Ġclass Generator . print ("${ allocated Value }. equals (${ allocated Value }) ") Ġ}, Ġblock , Ġelse Block ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Generator . if Block ({ Ġadd Inline MethodCall ( method To Call . variable , Ġmethod To Call . method ) Ġ}, Ġblock , Ġelse Block ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Lambda () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmethod To Call Ġ= Ġfind Method Return ing ( Iterable :: class . create Type ( listOf ( K Type Projection ( K Variance . OUT , ĠAny :: class . create Type ())) )) ĊĠĠĠĠĠĠĠ Ġval Ġbefore Block : Ġ(() Ġ-> ĠUnit )? Ġ= Ġif Ġ( method To Call Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġadd MethodCall ( method To Call . variable , Ġmethod To Call . method ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġclass Generator . lambda Block ( before Block ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . max NumberOf Blocks In Lambda Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( statement Index Ġin Ġ 0 .. random . nextInt ( params . max NumberOf Blocks In Lambda )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Block () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Method Return ing ( desired ReturnType : ĠK Type ): ĠMethod Call ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind Method Return ing ( class Generator . getMethod Parameters Variables (), Ġdesired ReturnType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġfind Method Return ing ( class Generator . getLocal Variables (), Ġdesired ReturnType ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Method Return ing ( field Models : ĠList < Field Model >, Ġdesired ReturnType : ĠK Type ): ĠMethod Call ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠstartIndex Ġ= Ġrandom . nextInt ( field Models . size ) ĊĠĠĠĠĠĠĠ Ġvar Ġmethod Call : ĠMethod Call ? ĊĠĠĠĠĠĠĠ Ġvar ĠcurrentIndex Ġ= ĠstartIndex ĊĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethod Call Ġ= Ġfind Method Return ing ( field Models [ currentIndex ], Ġdesired ReturnType ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentIndex Ġ= Ġ( currentIndex Ġ+ Ġ 1 ) Ġ% Ġfield Models . size ĊĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( method Call Ġ== Ġnull Ġ&& ĠstartIndex Ġ!= ĠcurrentIndex ) ĊĠĠĠĠĠĠĠ Ġreturn Ġmethod Call ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Method Return ing ( field Model : ĠField Model , Ġdesired ReturnType : ĠK Type ): ĠMethod Call ? Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO Ġ: Ġadd Ġsupport Ġfor Ġlooking Ġup Ġjava Ġmethods . Ġbe Ġaware Ġof Ġthe Ġissues Ġrelated Ġto Ġkotlin Ġreflection . Ċ // ĠĠĠĠĠĠĠ Ġfield Model . class Model . type . java . methods . filter Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġmethod Ġ-> Ġmethod . returnType . typeName Ġ== Ġdesired ReturnType . java Type . typeName Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġval Ġmethods With Correct ReturnType Ġ= Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfield Model . class Model . type . declared Functions . filter Ġ{ Ġmethod Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . returnType Ġ== Ġdesired ReturnType Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠ Ġfind Suit able Method To Call ( method sWith Correct ReturnType )?. let Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMethod Call ( field Model , Ġit ) Ċ // ĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġstring Class Model Ġ= ĠClass Model ( String :: class , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠString :: class . construct ors . first (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠString :: class . java . methods . map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ Ġit . kotlin Function Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ Ġnull Ġ} Ġ}) ĊĊĠĠĠ Ġprivate Ġfun Ġfind Suit able Type ( class Picker : ĠImport Class Picker ): ĠClass Model < *> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġselected Type Ġ= Ġclass Picker . pick Class ( random ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġapi Class Picker . pick Class ( random ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġselected Type Ġ?: Ġstring Class Model ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Suit able Method To Call ( methods : ĠCollection < K Function <* >> ): ĠK Function < *> ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsuitable Methods Ġ= Ġmethods ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . isNot Deprecated () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit . is Public () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit . all Parameters Can Be Instanti ated ( mutable ListOf < Class <* >> ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ( it . parameters . any Ġ{ Ġparameter Ġ-> Ġparameter . kind Ġ== ĠK Parameter . Kind . INSTANCE Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsuitable Methods . random OrNull ( random ) ĊĠĠĠ Ġ} Ċ }