package Ġcom . squareup . an vil . compiler . codegen . d agger Ċ Ċ import Ġcom . squareup . an vil . compiler . codegen . Code Generator . Generated File Ċ import Ġcom . squareup . an vil . compiler . codegen . Private Code Generator Ċ import Ġcom . squareup . an vil . compiler . codegen . as ArgumentList Ċ import Ġcom . squareup . an vil . compiler . codegen . as ClassName Ċ import Ġcom . squareup . an vil . compiler . codegen . build File Ċ import Ġcom . squareup . an vil . compiler . codegen . classes And Inner Classes Ċ import Ġcom . squareup . an vil . compiler . codegen . fq Name OrNull Ċ import Ġcom . squareup . an vil . compiler . codegen . inject Constructor Ċ import Ġcom . squareup . an vil . compiler . codegen . map To Parameter Ċ import Ġcom . squareup . an vil . compiler . generate ClassName Ċ import Ġcom . squareup . an vil . compiler . inject Fq Name Ċ import Ġcom . squareup . kotlin po et . ClassName Ċ import Ġcom . squareup . kotlin po et . File Spec Ċ import Ġcom . squareup . kotlin po et . Fun Spec Ċ import Ġcom . squareup . kotlin po et . K Modifier . OVERRIDE Ċ import Ġcom . squareup . kotlin po et . K Modifier . PRIVATE Ċ import Ġcom . squareup . kotlin po et . Parameterized TypeName . Companion . parameter ized By Ċ import Ġcom . squareup . kotlin po et . Property Spec Ċ import Ġcom . squareup . kotlin po et . Type Spec Ċ import Ġcom . squareup . kotlin po et . Type Variable Name Ċ import Ġcom . squareup . kotlin po et . as ClassName Ċ import Ġcom . squareup . kotlin po et . jvm . jvm Static Ċ import Ġdagger . internal . Factory Ċ import Ġorg . jetbrains . kotlin . descriptors . Module Descriptor Ċ import Ġorg . jetbrains . kotlin . psi . Kt Class Or Object Ċ import Ġorg . jetbrains . kotlin . psi . Kt Constructor Ċ import Ġorg . jetbrains . kotlin . psi . Kt File Ċ import Ġjava . io . File Ċ Ċ internal Ġclass ĠInject Constructor Factory Generator Ġ: ĠPrivate Code Generator () Ġ{ ĊĊĠ Ġoverride Ġfun Ġgenerate Code Private ( ĊĠĠĠ Ġcode Gen Dir : ĠFile , ĊĠĠĠ Ġmodule : ĠModule Descriptor , ĊĠĠĠ Ġproject Files : ĠCollection < Kt File > ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġproject Files ĊĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . classes And Inner Classes () Ġ} ĊĠĠĠĠĠ Ġ. forEach Ġ{ Ġclazz Ġ-> ĊĠĠĠĠĠĠĠ Ġclazz . inject Constructor ( inject Fq Name ) ĊĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgenerate Factory Class ( code Gen Dir , Ġmodule , Ġclazz , Ġit ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate Factory Class ( ĊĠĠĠ Ġcode Gen Dir : ĠFile , ĊĠĠĠ Ġmodule : ĠModule Descriptor , ĊĠĠĠ Ġclazz : ĠK t Class Or Object , ĊĠĠĠ Ġconstructor : ĠK t Constructor < *> ĊĠ Ġ): ĠGenerated File Ġ{ ĊĠĠĠ Ġval ĠpackageName Ġ= Ġclazz . containing Kt File . package Fq Name . asString () ĊĠĠĠ Ġval ĠclassName Ġ= Ġ"${ clazz . generate ClassName ()} _ Factory " ĊĊĠĠĠ Ġval Ġparameters Ġ= Ġconstructor . value Parameters . map To Parameter ( module ) ĊĊĠĠĠ Ġval Ġtype Parameters Ġ= Ġclazz . type Parameter List ĊĠĠĠĠĠ Ġ? . parameters ĊĠĠĠĠĠ Ġ? . map NotNull Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġextends Bound Ġ= Ġparameter . extends Bound ?. fq Name OrNull ( module )?. as ClassName ( module ) ĊĠĠĠĠĠĠĠ Ġif Ġ( parameter . fq Name OrNull ( module ) Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠType Variable Name ( parameter . name As Safe Name . asString (), ĠlistOf NotNull ( extends Bound )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ?: Ġempty List () ĊĊĠĠĠ Ġval Ġfactory Class Ġ= ĠClass Name ( packageName , ĠclassName ) ĊĠĠĠ Ġval Ġfactory Class Parameterized Ġ= ĊĠĠĠĠĠ Ġif Ġ( type Parameters . isEmpty ()) Ġfactory Class Ġelse Ġfactory Class . parameter ized By ( type Parameters ) ĊĊĠĠĠ Ġval Ġclass Type Ġ= Ġclazz . as ClassName (). let Ġ{ ĊĠĠĠĠĠ Ġif Ġ( type Parameters . isEmpty ()) Ġit Ġelse Ġit . parameter ized By ( type Parameters ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġcontent Ġ= ĠFile Spec . build File ( packageName , ĠclassName ) Ġ{ ĊĠĠĠĠĠ Ġval Ġcan Generate An Object Ġ= Ġparameters . isEmpty () ĊĠĠĠĠĠ Ġval Ġclass Builder Ġ= Ġif Ġ( can Generate An Object ) Ġ{ ĊĠĠĠĠĠĠĠ ĠType Spec . object Builder ( factory Class ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠType Spec . class Builder ( factory Class ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġtype Parameters . forEach Ġ{ Ġclass Builder . add Type Variable ( it ) Ġ} ĊĊĠĠĠĠĠ Ġclass Builder ĊĠĠĠĠĠĠĠ Ġ. add Super interface ( Factory :: class . as ClassName (). parameter ized By ( class Type )) ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( parameters . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprimary Constructor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFun Spec . constructor Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . forEach Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Parameter ( parameter . name , Ġparameter . provider TypeName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . forEach Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Property ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProperty Spec . builder ( parameter . name , Ġparameter . provider TypeName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. initializer ( parameter . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( PRIVATE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. addFunction ( ĊĠĠĠĠĠĠĠĠĠ ĠFun Spec . builder (" get ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( OVERRIDE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( class Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargument List Ġ= Ġparameters . as ArgumentList ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġas Provider Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinclude Module Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Statement (" return Ġnew Instance ($ argument List )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= Ġif Ġ( can Generate An Object ) Ġthis Ġelse ĠType Spec . comp anion Object Builder () ĊĠĠĠĠĠĠĠĠĠ Ġbuilder ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addFunction ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFun Spec . builder (" create ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. jvm Static () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Parameters . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Type Variables ( type Parameters ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( can Generate An Object ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Statement (" return Ġthis ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . forEach Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Parameter ( parameter . name , Ġparameter . provider TypeName ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargument List Ġ= Ġparameters . as ArgumentList ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġas Provider Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinclude Module Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Statement ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" return Ġ% T ($ argument List )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfactory Class Parameterized ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( factory Class Parameterized ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. addFunction ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFun Spec . builder (" newInstance ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. jvm Static () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( type Parameters . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Type Variables ( type Parameters ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters . forEach Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Parameter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġparameter . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Ġ= Ġparameter . original TypeName ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments Without Module Ġ= Ġparameters . join ToString Ġ{ Ġit . name Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Statement (" return Ġ% T ($ arguments Without Module )", Ġclass Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( class Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! can Generate An Object ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Type ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ. let Ġ{ Ġadd Type ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġcreate Generated File ( code Gen Dir , ĠpackageName , ĠclassName , Ġcontent ) ĊĠ Ġ} Ċ } Ċ