/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠL ala fo . Ċ Ġ* Ċ Ġ* Ġ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 . l ala fo . codegen . processor . injection Ċ Ċ import Ġcom . google . auto . common . More Elements Ċ import Ġcom . google . auto . common . More Types Ċ import Ġcom . google . auto . service . Auto Service Ċ import Ġcom . l ala fo . codegen . injection . Inject Controller Ċ import Ġcom . l ala fo . codegen . injection . Controller Bundle Ċ import Ġcom . l ala fo . codegen . processor . internal .* Ċ import Ġcom . squareup . jav ap o et . Java File Ċ import Ġnet . lt gt . gradle . inc ap . Incremental Annotation Processor Ċ import Ġnet . lt gt . gradle . inc ap . Incremental Annotation Processor Type Ċ import Ġjavax . annotation . processing .* Ċ import Ġjavax . lang . model . Source Version Ċ import Ġjavax . lang . model . element .* Ċ import Ġjavax . lang . model . type . Declared Type Ċ import Ġjavax . lang . model . type . Executable Type Ċ import Ġjavax . lang . model . util . Elements Ċ import Ġjavax . lang . model . util . Types Ċ import Ġjavax . tools . Diagnostic Ċ Ċ @ Incremental Annotation Processor ( Incremental Annotation Processor Type . IS OL ATING ) Ċ @ Auto Service ( Processor :: class ) Ċ class ĠController Injection Processor Ġ: ĠAbstract Processor () Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġsource Version : ĠSource Version ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmess ager : ĠMess ager ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġf iler : ĠF iler ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġelements : ĠElements ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġtypes : ĠTypes ĊĊĠĠĠ Ġoverride Ġfun Ġinit ( env : ĠProcessing Environment ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . init ( env ) ĊĠĠĠĠĠĠĠ Ġsource Version Ġ= Ġenv . source Version ĊĠĠĠĠĠĠĠ Ġmess ager Ġ= Ġenv . mess ager ĊĠĠĠĠĠĠĠ Ġf iler Ġ= Ġenv . filer ĊĠĠĠĠĠĠĠ Ġelements Ġ= Ġenv . element Utils ĊĠĠĠĠĠĠĠ Ġtypes Ġ= Ġenv . type Utils ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Supported Source Version (): ĠSource Version Ġ= ĠSource Version . latest () ĊĊĠĠĠ Ġoverride Ġfun Ġget Supported Annotation Types (): ĠSet < String > Ġ= Ġset Of ( ĊĠĠĠĠĠĠĠ ĠController Bundle :: class . java . canonical Name , ĊĠĠĠĠĠĠĠ ĠInject Controller :: class . java . canonical Name , ĊĠĠĠĠĠĠĠ ĠInject Controller . Factory :: class . java . canonical Name ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġoverride Ġfun Ġprocess ( annotations : ĠMutable Set < out ĠType Element >, Ġround Env : ĠRound Environment ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġround Env . findAll Injection Candidates () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ Ġit . to Controller Inject Elements OrNull () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. associate With Ġ{ Ġit . to Controller Injection OrNull () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter NotNull Values () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach (:: write Controller Injection ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcontroller Argument Methods Ġ= Ġround Env . find Elements Annotated With < Controller Bundle >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . enc lo sing Element Ġas ĠExec utable Element Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠError Ġany Ġnon - constructor Ġusage Ġof Ġ@ Controller Bundle . ĊĠĠĠĠĠĠĠ Ġcontroller Argument Methods ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Not Ġ{ Ġit . simple Name . content Equals ("< init >") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Controller Bundle Ġis Ġonly Ġsupported Ġon Ġconstructor Ġparameters ", Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠError Ġany Ġconstructor Ġusage Ġof Ġ@ Controller Bundle Ġwhich Ġlack s Ġmethod Ġannotations . ĊĠĠĠĠĠĠĠ Ġcontroller Argument Methods ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . simple Name . content Equals ("< init >") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . annotation Mir rors . isEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"@ Controller Bundle Ġparameter Ġuse Ġrequires Ġa Ġconstructor Ġannotation Ġsuch Ġas Ġ@ Inject Controller .", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠError Ġany Ġconstructor Ġusage Ġof Ġ@ Controller Bundle Ġwhich Ġalso Ġuses Ġ@ Inject . ĊĠĠĠĠĠĠĠ Ġcontroller Argument Methods ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . simple Name . content Equals ("< init >") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . has Annotation (" javax . inject . Inject ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Controller Bundle Ġparameter Ġdoes Ġnot Ġwork Ġwith Ġ@ Inject ! ĠUse Ġ@ Inject Controller !", Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠRound Environment . findAll Injection Candidates (): ĠList < Type Element > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconstructors Ġ= Ġfind Elements Annotated With < Inject Controller >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . enc lo sing Element Ġas ĠType Element Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġ( enc losed , Ġorphan ed ) Ġ= Ġfind Elements Annotated With < Inject Controller . Factory >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. partition Ġ{ Ġit . enc lo sing Element . kind Ġ== ĠElement Kind . CLASS Ġ} ĊĊĠĠĠĠĠĠĠ Ġorphan ed . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Inject Controller . Factory Ġmust Ġbe Ġdeclared Ġas Ġa Ġnested Ġtype ", Ġit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfactories Ġ= Ġen closed . map Ġ{ Ġit . enc lo sing Element Ġas ĠType Element Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġ( factories Ġ+ Ġconstructors ). distinct By Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMore Types . equiv al ence (). wrap ( it . as Type ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠType Element . to Controller Inject Elements OrNull (): ĠController Inject Elements ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġvalid Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġif Ġ( Modifier . PRIVATE Ġin Ġmodifiers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Inject Controller - using Ġtypes Ġmust Ġbe Ġnot Ġprivate ", Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( enc lo sing Element . kind Ġ== ĠElement Kind . CLASS Ġ&& ĠModifier . STATIC Ġ! in Ġmodifiers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Nested Ġ@ Inject Controller - using Ġtypes Ġmust Ġbe Ġstatic ", Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġconstructors Ġ= Ġen closed Elements ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . kind Ġ== ĠElement Kind . CON STRUCTOR Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . has Annotation < Inject Controller >() Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. cast Each < Executable Element >() ĊĊĠĠĠĠĠĠĠ Ġif Ġ( construct ors . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Controller Ġinjection Ġrequires Ġan Ġ@ Inject Controller - annotated Ġconstructor .", Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( construct ors . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Multiple Ġ@ Inject Controller Ġconstructs Ġfound .", Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnested Factories Types Ġ= Ġen closed Elements ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . has Annotation < Inject Controller . Factory >() Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. cast Each < Type Element >() ĊĊĠĠĠĠĠĠĠ Ġif Ġ( nested Factories Types . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Multiple Ġcontroller Ġfactories Ġannotated Ġwith Ġ@ Inject Controller . Factory Ġfound .", Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! valid ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġ// ĠTrying Ġto Ġconstruct Ġelements Ġhere ĊĠĠĠĠĠĠĠ Ġval Ġinjection Constructor Ġ= Ġconstructors . single () ĊĠĠĠĠĠĠĠ Ġif Ġ( Modifier . PRIVATE Ġin Ġinjection Constructor . modifiers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Inject Controller Ġconstructor Ġ Ġmust Ġbe Ġnot Ġprivate .", Ġinjection Constructor ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfactory Type Ġ= Ġnested Factories Types . first OrNull () ĊĠĠĠĠĠĠĠ Ġvar Ġfactory Method : ĠExec utable Element ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( factory Type Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġfactory Ġhere ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( factory Type . kind Ġ!= ĠElement Kind . INTERFACE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Inject Controller . Factory Ġmust Ġbe Ġan Ġinterface .", Ġfactory Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Modifier . PRIVATE Ġin Ġfactory Type . modifiers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("@ Inject Controller . Factory Ġmust Ġbe Ġnot Ġprivate .", Ġfactory Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Methods Ġ= ĠMore Elements . getLocal And Inherited Methods ( factory Type , Ġtypes , Ġelements ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Not Ġ{ Ġit . is Default Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( factory Methods . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Factory Ġinterface Ġdoes Ġnot Ġdefine Ġa Ġfactory Ġmethod .", Ġfactory Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( factory Methods . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Factory Ġinterface Ġdefines Ġmultiple Ġfactory Ġmethods .", Ġfactory Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! valid ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Method Ġ= Ġfactory Methods . single () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠController Inject Elements ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinjection Constructor , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Type , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Method ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠController Inject Elements . to Controller Injection OrNull (): ĠController Injection ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġvalid Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġval Ġcontroller Ġ= Ġelements . getType Element (" com . blue lin el abs . cond uctor . Controller "). as Type () ĊĠĠĠĠĠĠĠ Ġval Ġis Controller Ġ= Ġtypes . is Assignable ( target Type . as Type (), Ġcontroller ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Controller ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Using Ġ@ Inject Controller Ġannotation Ġon Ġnon ĠController Ġclass .", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Constructor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! valid ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġcontroller Args Ġ= Ġelements . getType Element (" com . blue lin el abs . cond uctor . Controller Args "). as Type () ĊĠĠĠĠĠĠĠ Ġval Ġdependency Requests Ġ= Ġtarget Constructor . parameters . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . as Dependency Request ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Args Ġ= Ġcontroller Args , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtypes Ġ= Ġtypes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġ( arguments Requests , Ġprovider Requests ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdependency Requests . partition Ġ{ Ġit . is Controller Args Ġ} ĊĊĠĠĠĠĠĠĠ Ġprovider Requests . filter Ġ{ Ġit . has Bundle Annotation Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Using Ġ@ Controller Bundle Ġannotation Ġon Ġinjection Ġprovided Ġtype .", Ġtarget Constructor ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( arguments Requests . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Found Ġmore Ġthan Ġone Ġcontroller Ġbundle Ġarguments Ġat Ġ@ Inject Controller - annotated Ġconstructor ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Constructor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( arguments Requests . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargument Request Ġ= Ġarguments Requests . single () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! argument Request . has Bundle Annotation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwarn (" Controller Ġbundle Ġargument Ġ'${ argument Request . named Key . name }' Ġis Ġnot Ġannotated Ġwith Ġ@ Controller Bundle ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( argument Request . name Ġ== Ġ" inst anti ation Arguments ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("\" inst anti ation Arguments \" Ġargument Ġname Ġfor Ġ@ Inject Controller - annotated Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" controller Ġis Ġforbidden , Ġtry Ġanother Ġone .", Ġtarget Constructor ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġfactory Executable : ĠExec utable Type ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġfactory Arguments Ġ= Ġmutable ListOf < Named Key >() ĊĠĠĠĠĠĠĠ Ġif Ġ( factory Type Ġ!= Ġnull Ġ&& Ġfactory Method Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Executable Ġ= Ġtypes . as Member Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Type . as Type () Ġas ĠDecl ared Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Method ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġas ĠExec utable Type ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( factory Method . simple Name . toString () Ġ== Ġ" newInstance With Arguments ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ("\" newInstance With Arguments \" Ġmethod Ġname Ġfor Ġ@ Inject Controller . Factory - annotated Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" interface Ġis Ġforbidden , Ġtry Ġanother Ġname .", Ġfactory Method ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Keys Ġ= Ġarguments Requests . map Ġ{ Ġit . named Key Ġ}. sorted () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Keys Ġ= Ġfactory Method . parameters ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. zip ( factory Executable . parameter Types ) Ġ{ Ġelement , Ġmirror Ġ-> Ġelement . as Named Key ( mirror ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Arguments . addAll ( factory Keys ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkeys Ġ= Ġfactory Keys . sorted () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( keys Ġ!= Ġexpected Keys ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġbuild String Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend (" Factory Ġmethod Ġparameters Ġdo Ġnot Ġmatch Ġconstructor Ġ@ Controller Bundle Ġparameters . Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend (" Both Ġparameter Ġtype Ġand Ġname Ġmust Ġmatch .") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Keys Ġ= Ġexpected Keys Ġ- Ġkeys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( missing Keys . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmissing Keys . join ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\ n Ġ* Ġ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ"\ n Declared Ġby Ġconstructor , Ġun matched Ġin Ġfactory Ġmethod :\ n Ġ* Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġunknown Keys Ġ= Ġkeys Ġ- Ġexpected Keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( unknown Keys . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġunknown Keys . join ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\ n Ġ* Ġ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprefix Ġ= Ġ"\ n Declared Ġby Ġfactory Ġmethod , Ġun matched Ġin Ġconstructor :\ n Ġ* Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( factory Method . enc lo sing Element Ġ== Ġfactory Type ) Ġfactory Method Ġelse Ġtarget Constructor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! valid ) Ġreturn Ġnull ĊĊĊĠĠĠĠĠĠĠ Ġval Ġtarget Type Ġ= Ġtarget Type . as Type (). to TypeName () ĊĊĠĠĠĠĠĠĠ Ġval Ġfactory Type Ġ= Ġfactory Type ?. to ClassName () ĊĠĠĠĠĠĠĠ Ġval ĠreturnType Ġ= Ġfactory Executable ?. returnType ?. to TypeName () ĊĠĠĠĠĠĠĠ Ġval ĠmethodName Ġ= Ġfactory Method ?. simple Name ?. toString () ĊĊĠĠĠĠĠĠĠ Ġval Ġgenerated Annotation Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Generated Annotation ( source Version , Ġelements ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠController Injection ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Type , Ġdependency Requests , Ġfactory Type , ĠmethodName , ĠreturnType , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Arguments , Ġgenerated Annotation ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite Controller Injection ( ĊĠĠĠĠĠĠĠ Ġelements : ĠController Inject Elements , ĊĠĠĠĠĠĠĠ Ġinjection : ĠController Injection ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġgenerated Type Spec Ġ= Ġinjection . brew Java () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Origin ating Element ( elements . target Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ ĠJava File . builder ( injection . generated Type . packageName (), Ġgenerated Type Spec ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add File Comment (" Generated Ġby Ġ@ Inject Controller . ĠDo Ġnot Ġmodify !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. writeTo ( filer ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwarn ( message : ĠString , Ġelement : ĠElement ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmess ager . print Message ( Diagnostic . Kind . WARNING , Ġmessage , Ġelement ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġerror ( message : ĠString , Ġelement : ĠElement ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmess ager . print Message ( Diagnostic . Kind . ERROR , Ġmessage , Ġelement ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġdata Ġclass ĠController Inject Elements ( ĊĠĠĠĠĠĠĠ Ġval Ġtarget Type : ĠType Element , ĊĠĠĠĠĠĠĠ Ġval Ġtarget Constructor : ĠExec utable Element , ĊĠĠĠĠĠĠĠ Ġval Ġfactory Type : ĠType Element ?, ĊĠĠĠĠĠĠĠ Ġval Ġfactory Method : ĠExec utable Element ? ĊĠĠĠ Ġ) Ċ }