/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 8 ĠSer ge j ĠSh af aren ka , Ġwww . half bit . de Ċ Ġ* Ċ Ġ* Ġ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 Ġmag net . processor . instances . generator Ċ Ċ import Ġcom . squareup . jav ap o et . ClassName Ċ import Ġcom . squareup . jav ap o et . Method Spec Ċ import Ġcom . squareup . jav ap o et . Parameterized TypeName Ċ import Ġcom . squareup . jav ap o et . TypeName Ċ import Ġcom . squareup . jav ap o et . Type Spec Ċ import Ġmag net . internal . Generated Ċ import Ġmag net . internal . Instance Factory Ċ import Ġmag net . processor . instances . Create Method Ċ import Ġmag net . processor . instances . Factory Type Ċ import Ġmag net . processor . instances . Factory Type Visitor Ċ import Ġmag net . processor . instances . Get Limit Method Ċ import Ġmag net . processor . instances . Get S co ping Method Ċ import Ġmag net . processor . instances . Get Selector Method Ċ import Ġmag net . processor . instances . Get Sibling Types Method Ċ import Ġmag net . processor . instances . Method Parameter Ċ import Ġmag net . processor . instances . aspect s . limited to . Get Limit Method Generator Ċ import Ġmag net . processor . instances . aspect s . selector . Get Selector Method Generator Ċ import Ġmag net . processor . instances . aspect s . dis poser . Dispose Method Generator Ċ import Ġmag net . processor . instances . aspect s . dis poser . Is Disposable Method Generator Ċ import Ġmag net . processor . instances . aspect s . factory . Create Method Generator Ċ import Ġmag net . processor . instances . aspect s . factory . Default Create Method Generator Ċ import Ġmag net . processor . instances . aspect s . sco ping . Get S co ping Method Generator Ċ import Ġmag net . processor . instances . aspect s . siblings . Get Sibling Types Method Generator Ċ import Ġjavax . lang . model . element . Modifier Ċ Ċ interface ĠAs pect Generator Ġ{ ĊĠĠĠ Ġfun Ġgenerate ( class Builder : ĠType Spec . Builder ) ĊĠĠĠ Ġfun Ġreset () Ċ } Ċ Ċ internal Ġclass ĠAs pect < out ĠG Ġ: ĠAs pect Generator >( ĊĠĠĠ Ġprivate Ġval Ġgenerator : ĠG Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġvisited : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġinline Ġfun Ġvisit ( block : ĠG . () Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġblock ( generator ) ĊĠĠĠĠĠĠĠ Ġvisited Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġgenerate ( class Builder : ĠType Spec . Builder ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( visited ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgenerator . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġgenerator . reset () ĊĠĠĠĠĠĠĠ Ġvisited Ġ= Ġfalse ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠFactory TypeCode Generator Ġ: ĠFactory Type Visitor , ĠCode Generator Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġfactory Type Spec : ĠType Spec ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġfactory ClassName : ĠClass Name ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġgenerate Get ters In Create Method Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġval Ġaspect Get Sibling Types Ġ= ĠAs pect ( Get Sibling Types Method Generator ()) ĊĠĠĠ Ġprivate Ġval Ġaspect Get S co ping Ġ= ĠAs pect ( Get S co ping Method Generator ()) ĊĠĠĠ Ġprivate Ġval Ġaspect Get Limit Ġ= ĠAs pect ( Get Limit Method Generator ()) ĊĠĠĠ Ġprivate Ġval Ġaspect Get Selector Ġ= ĠAs pect ( Get Selector Method Generator ()) ĊĠĠĠ Ġprivate Ġval Ġcreate Method Generator : ĠCreate Method Generator Ġ= ĠDefault Create Method Generator () ĊĠĠĠ Ġprivate Ġval Ġis Disposable Method Generator Ġ= ĠIs Disposable Method Generator () ĊĠĠĠ Ġprivate Ġval Ġdispose Method Generator Ġ= ĠDispose Method Generator () ĊĊĠĠĠ Ġoverride Ġfun Ġenter Factory Class ( factory Type : ĠFactory Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgenerate Get ters In Create Method Ġ= Ġfactory Type . custom Factory Type Ġ== Ġnull ĊĠĠĠĠĠĠĠ Ġcreate Method Generator . visit Factory Class ( factory Type ) ĊĠĠĠĠĠĠĠ Ġis Disposable Method Generator . visit Factory Class ( factory Type ) ĊĠĠĠĠĠĠĠ Ġdispose Method Generator . visit Factory Class ( factory Type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenter Create Method ( create Method : ĠCreate Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfactory Type Spec Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġcreate Method Generator . enter Create Method ( create Method ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Create Method Parameter ( parameter : ĠMethod Parameter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcreate Method Generator . visit Create Method Parameter ( parameter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġexit Create Method ( create Method : ĠCreate Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcreate Method Generator . exit Create Method () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit ( method : ĠGet S co ping Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get S co ping . visit Ġ{ Ġvisit ( method ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit ( method : ĠGet Limit Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Limit . visit Ġ{ Ġvisit ( method ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenter Sibling Types Method ( method : ĠGet Sibling Types Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Sibling Types . visit Ġ{ Ġenter Sibling Types Method ( method ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Sibling Type ( type : ĠClass Name ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Sibling Types . visit Ġ{ Ġvisit Sibling Type ( type ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġexit Sibling Types Method ( method : ĠGet Sibling Types Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Sibling Types . visit Ġ{ Ġexit Sibling Types Method () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenter Get Selector Method ( method : ĠGet Selector Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Selector . visit Ġ{ Ġenter Get Selector Method ( method ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Selector Argument ( argument : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Selector . visit Ġ{ Ġvisit Selector Argument ( argument ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġexit Get Selector Method ( method : ĠGet Selector Method ) Ġ{ ĊĠĠĠĠĠĠĠ Ġaspect Get Selector . visit Ġ{ Ġexit Get Selector Method () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġexit Factory Class ( factory : ĠFactory Type ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfactory ClassName Ġ= Ġfactory . factory Type ĊĊĠĠĠĠĠĠĠ Ġval Ġclass Builder : ĠType Spec . Builder Ġ= ĠType Spec ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. class Builder ( factory ClassName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC , ĠModifier . FINAL ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Annotation ( Generated :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. super class ( generate Factory Super Interface ( factory )) ĊĊĠĠĠĠĠĠĠ Ġcreate Method Generator . generate ( class Builder ) ĊĊĠĠĠĠĠĠĠ Ġaspect Get S co ping . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġaspect Get Limit . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġaspect Get Sibling Types . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġaspect Get Selector . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġis Disposable Method Generator . generate ( class Builder ) ĊĠĠĠĠĠĠĠ Ġdispose Method Generator . generate ( class Builder ) ĊĊĠĠĠĠĠĠĠ Ġclass Builder ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Method ( generate GetType Method ( factory )) ĊĊĠĠĠĠĠĠĠ Ġfactory Type Spec Ġ= Ġclass Builder . build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgenerate GetType Method ( factory Type : ĠFactory Type ): ĠMethod Spec Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠMethod Spec ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. method Builder (" getType ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC , ĠModifier . STATIC ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( Class :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Statement (" return Ġ\$ T . class ", Ġfactory Type . interface Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġgenerate Factory Super Interface ( factory Type : ĠFactory Type ): ĠType Name Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠParameter ized TypeName . get ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠClass Name . get ( Instance Factory :: class . java ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Type . interface Type ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġgenerate From ( factory Type : ĠFactory Type ): ĠCode Writer Ġ{ ĊĠĠĠĠĠĠĠ Ġfactory Type . accept ( this ) ĊĠĠĠĠĠĠĠ Ġreturn ĠCode Writer ( this . factory ClassName !!. packageName (), Ġfactory Type Spec !! ) ĊĠĠĠ Ġ} Ċ } Ċ