package Ġkr . spark web . multi platform . processor Ċ Ċ import Ġcom . squareup . jav ap o et . Java File Ċ import Ġcom . squareup . jav ap o et . Method Spec Ċ import Ġcom . squareup . kotlin po et . ClassName Ċ import Ġcom . squareup . kotlin po et . Parameter Spec Ċ import Ġcom . squareup . kotlin po et . Type Spec Ċ import Ġcom . squareup . kotlin po et . jav ap o et . to J TypeName Ċ import Ġcom . squareup . kotlin po et . metadata . class inspect ors . Elements Class Inspector Ċ import Ġcom . squareup . kotlin po et . metadata . specs . to Type Spec Ċ import Ġkr . spark web . multi platform . annotation . Provide With D agger Ċ import Ġdagger . Module Ċ import Ġdagger . Provides Ċ import Ġjavax . annotation . processing . Abstract Processor Ċ import Ġjavax . annotation . processing . Round Environment Ċ import Ġjavax . lang . model . Source Version Ċ import Ġjavax . lang . model . element . Element Kind Ċ import Ġjavax . lang . model . element . Modifier Ċ import Ġjavax . lang . model . element . Type Element Ċ import Ġjavax . tools . Diagnostic Ċ Ċ class ĠProcessor Ġ: ĠAbstract Processor () Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġprocess ( ĊĠĠĠĠĠĠĠ Ġelements : ĠMutable Set < out ĠType Element > ?, ĊĠĠĠĠĠĠĠ Ġround Env : ĠRound Environment ĊĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmodule PackageName Ġ= Ġprocessing Env . options [" module Package "] Ġ?: Ġ"" ĊĊĠĠĠĠĠĠĠ Ġval Ġproviding Classes Ġ= Ġmutable Map Of < ClassName , ĠType Spec >() ĊĠĠĠĠĠĠĠ Ġval Ġmodule Names Ġ= Ġmutable Map Of < String , ĠArrayList < ClassName >>() ĊĊĠĠĠĠĠĠĠ Ġval Ġclass Inspector Ġ= ĠElements Class Inspector . create ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . element Utils , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . type Utils ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( element Ġin Ġround Env . getElement s Annotated With ( Provide With D agger :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠmoduleName Ġ= Ġelement . getAnnotation ( Provide With D agger :: class . java ). moduleName ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( moduleName . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Module Ġname Ġcannot Ġbe Ġblank ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġannotated Ġelement Ġis Ġa Ġclass ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( element . kind Ġ!= ĠElement Kind . CLASS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Annotated Ġtype Ġis Ġnot Ġclass Ġ: Ġ${ element . simple Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= ĠClass Name ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . element Utils . get Package Of ( element ). toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelement . simple Name . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Spec Ġ= Ġ( element Ġas ĠType Element ). to Type Spec ( class Inspector ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġth eres Ġonly Ġ 1 Ġconstructor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprimary Constructor Count Ġ= Ġif Ġ( class Spec . primary Constructor Ġ!= Ġnull ) Ġ 1 Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconstructors Ġ= Ġclass Spec . fun Specs . count Ġ{ Ġit . is Constructor Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( primary Constructor Count Ġ+ Ġconstructors Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" Can 't Ġdecide Ġhow Ġto Ġinstantiate Ġannotated Ġclass Ġ: Ġ${ className . simple Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pro viding Classes . containsKey ( className )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror (" D uplicated Ġproviding Ġclasses Ġ: Ġ${ className . simple Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġproviding Classes [ className ] Ġ= Ġclass Spec ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodule Names [ moduleName ]?. add ( className ) Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodule Names [ moduleName ] Ġ= Ġarray ListOf ( className ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġprevent Ġover writing Ġby Ġprocessing Ġrounds ĊĠĠĠĠĠĠĠ Ġif Ġ( pro viding Classes . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmodule Names . forEach Ġ{ Ġ( moduleName , ĠclassNames ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclasses Ġ= Ġproviding Classes . filter Ġ{ ĠclassNames . contains ( it . key ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJava File . builder ( module PackageName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcom . squareup . jav ap o et . Type Spec . class Builder ("${ moduleName } Module ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Annotation ( Module :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Methods ( classes . to Methods ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. writeTo ( processing Env . filer ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Supported Annotation Types () Ġ= Ġmutable Set Of ( ĊĠĠĠĠĠĠĠ ĠProvide With D agger :: class . java . canonical Name ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġoverride Ġfun Ġget Supported Source Version (): ĠSource Version Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠSource Version . latest Supported () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠMap < ClassName , ĠType Spec >. to Methods () Ġ= Ġmap Ġ{ Ġ( className , Ġspec ) Ġ-> ĊĠĠĠĠĠĠĠ ĠclassName . generate Pro viding Method ( spec ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠClass Name . generate Pro viding Method ( spec : ĠType Spec ): ĠMethod Spec Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconstructor Ġ= Ġspec . primary Constructor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġspec . fun Specs . first Ġ{ Ġit . is Constructor Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġinit Statement Ġ= Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Ġ( StringBuilder (" return Ġnew Ġ\$ N (" )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġconstructor . parameters . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( index , Ġparams ) Ġin Ġconstructor . parameters . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend ( params . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( index Ġ!= Ġsize Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend (", Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend (" )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠMethod Spec . method Builder (" provide $ simple Name ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Annotation ( Provides :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Parameters ( constructor . parameters . map Ġ{ Ġit . to Java Parameter Spec () Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( this . to J TypeName ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Statement ( init Statement , Ġsimple Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠParameter Spec . to Java Parameter Spec () Ġ= Ġcom . squareup . jav ap o et . Parameter Spec ĊĠĠĠĠĠĠĠ Ġ. builder ( type . to J TypeName (), Ġname ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġprivate Ġfun Ġerror ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprocessing Env . mess ager . print Message ( Diagnostic . Kind . ERROR , Ġmessage ) ĊĠĠĠ Ġ} Ċ } Ċ