package Ġcom . just . app . r . inline . plugin Ċ Ċ import ĠJust App . r . inline . plugin . Build Ċ import Ġcom . base . app . asm . Class Transformer Ċ import Ġcom . base . app . spi . transformer . Artifact Manager Ċ import Ġcom . base . app . spi . transformer . Artifact Manager . Companion . SYMBOL _ LIST Ċ import Ġcom . base . app . spi . transformer . Transform Context Ċ import Ġcom . base . app . spi . util . as Iterable Ċ import Ġcom . base . app . spi . util . file Ċ import Ġcom . base . app . spi . util . touch Ċ import Ġcom . google . auto . service . Auto Service Ċ import Ġcom . just . app . r . inline . plugin . Symbols List . getInt Ċ import Ġcom . just . app . r . inline . plugin . Symbols List . parse R txt File Ċ import Ġj dk . internal . org . object web . asm . Op codes Ċ import Ġorg . object web . asm . tree . Class Node Ċ import Ġorg . object web . asm . tree . Field Insn Node Ċ import Ġorg . object web . asm . tree . L dc Insn Node Ċ import Ġjava . io . PrintWriter ĊĊ Ċ @ Auto Service ( Class Transformer :: class ) Ċ public Ġclass ĠR Inline Transform Ġ: ĠClass Transformer Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠR _ STYLE ABLE Ġ= Ġ" R \$ style able " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠPR FIX _ ANDROID _ CON STR A IT _ LAYOUT Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġcom . android . support . constraint / constraint - layout " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠPR FIX _ AND RO IDX _ CON STR A IT _ LAYOUT Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġandroidx . constraint layout . widget / constraint layout " ĊĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠCOM _ ANDROID _ INTERNAL _ R Ġ= Ġ" com / android / internal / R $" ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠAND ROID _ R Ġ= Ġ" android / R $" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġapp Pkg : ĠString ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġlogger : ĠPrintWriter ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġsymbols : ĠList < Symbols <* >> ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġapp R St yl able : ĠString ĊĊĠĠĠ Ġoverride Ġfun Ġon Pre Transform ( context : ĠTransform Context ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Pre Transform ( context ) ĊĠĠĠĠĠĠĠ Ġthis . app Pkg Ġ= Ġcontext . original Application Id . replace (".", Ġ"/") ĊĠĠĠĠĠĠĠ Ġapp R St yl able Ġ= Ġ"$ app Pkg /$ R _ STYLE ABLE " ĊĠĠĠĠĠĠĠ Ġthis . logger Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . reports Dir . file ( Build . AR TI FACT ). file ( context . name ). file (" report . txt "). touch () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. print Writer () ĊĊĠĠĠĠĠĠĠ Ġ// è§£æŀĲ app / build / inter midi ates / r unt im _ syn mb ol _ list / R . txt Ġæĸĩä»¶ ĊĠĠĠĠĠĠĠ Ġsymbols Ġ= Ġparse R txt File ( context . artifacts . get ( SYMBOL _ LIST ). single ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġcls Path Ġ= Ġcontext . compile Classpath . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . absolute Path ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( cls Path . any Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . contains ( PR FIX _ ANDROID _ CON STR A IT _ LAYOUT ) Ġ|| Ġit . contains ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPR FIX _ AND RO IDX _ CON STR A IT _ LAYOUT ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . artifacts . get ( Artifact Manager . MER GED _ RES ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// remove ĠR . class Ġfile ĊĠĠĠĠĠĠĠ Ġ// ä¸į åħ¼ å®¹ AG P Ġ 3 . 6 . 1 + Ġ çīĪæľ¬ ĊĠĠĠĠĠĠĠ Ġ/* val Ġr Files Ġ= Ġcontext . getR Class File () ĊĠĠĠĠĠĠĠ Ġr Files . forEach Ġ{ Ġpair Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpair . first . delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . logger . println (" remove Ġname Ġ= Ġ${ pair . second } Ġ& Ġfile Ġ=> Ġ${ pair . first . absolute Path }") ĊĠĠĠĠĠĠĠ Ġ}*/ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* Ġprivate Ġfun ĠTransform Context . getR Class File (): ĠList < Pair < File , ĠString >> Ġ{ ĊĠĠĠĠĠĠĠĠ Ġreturn Ġartifacts . get ( Artifact Manager . ALL _ CLASSES ). map Ġ{ Ġclasses Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbase Uri Ġ= Ġclasses . to URI () ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġclasses . search Ġ{ Ġr Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġr . name . startsWith (" R ") Ġ&& Ġr . name . endsWith (". class ") Ġ&& Ġ( r . name [ 1 ] Ġ== Ġ'$ ' Ġ|| Ġr . name . length Ġ== Ġ 7 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. map Ġ{ Ġr Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġr Ġto Ġbase Uri . rel ativ ize ( r . to URI ()). path . substring Before (". class ") ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠ Ġ}. flatten (). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . second Ġ!= Ġapp R St yl able ĊĠĠĠĠĠĠĠĠ Ġ}. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠ Ġ}*/ ĊĊĠĠĠ Ġoverride Ġfun Ġtransform ( context : ĠTransform Context , Ġklass : ĠClass Node ): ĠClass Node Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( symbols . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsuper . transform ( context , Ġklass ) ĊĠĠĠĠĠĠĠ Ġval Ġcls name Ġ= Ġklass . name . substring ( klass . name . lastIndexOf ("/") Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( cls name . startsWith (" R \$ ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ä¿ĿçķĻ app ĠR $ style able ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( klass . name Ġ== Ġapp R St yl able ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġklass ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġklass . fields . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . logger . println (" delete ĠR Ġclass Ġfield Ġ: Ġclassname Ġ= Ġ${ it . name } Ġ&& Ġ${ it . desc }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġklass . fields . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġklass ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġklass . replace R With Constant () ĊĠĠĠĠĠĠĠ Ġreturn Ġklass ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Post Transform ( context : ĠTransform Context ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Post Transform ( context ) ĊĠĠĠĠĠĠĠ Ġthis . logger . println (" on Post Transform () ") ĊĠĠĠĠĠĠĠ Ġprintln (" on Post Transform () Ġ") ĊĠĠĠĠĠĠĠ Ġthis . logger . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠClass Node . replace R With Constant () Ġ{ ĊĠĠĠĠĠĠĠ Ġmethods . forEach Ġ{ Ġmethods Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfields Ġ= Ġmethods . instructions . iterator (). as Iterable (). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . opcode Ġ== ĠOp codes . GET STATIC ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġas ĠField Insn Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ(" I " Ġ== Ġit . desc Ġ|| Ġ"[ I " Ġ== Ġit . desc ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit . owner . substring ( it . owner . lastIndexOf ('/') Ġ+ Ġ 1 ). startsWith (" R $ ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ!( it . owner . startsWith ( COM _ ANDROID _ INTERNAL _ R ) Ġ|| Ġit . owner . startsWith ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAND ROID _ R ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġint Fields Ġ= Ġfields . filter Ġ{ Ġit . desc Ġ== Ġ" I " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠintArray Fields Ġ= Ġfields . filter Ġ{ Ġit . desc Ġ== Ġ"[ I " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġint Fields . forEach Ġ{ Ġfield Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġfield . owner . substring ( field . owner . lastIndexOf ("/ R \$ ") Ġ+ Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethods . instructions . insertBefore ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠL dc Insn Node ( symbols . getInt ( type , Ġfield . name )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethods . instructions . remove ( field ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . println ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ* Ġ${ field . owner }.${ field . name } Ġ=> Ġ${ symbols . getInt ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) }: Ġ$ name .${ methods . name }${ methods . desc }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . println (" Ġ! ĠUn res olvable Ġsymbol Ġ`${ field . owner }.${ field . name }` : Ġ$ name .${ methods . name }${ methods . desc }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠintArray Fields . forEach Ġ{ Ġfield Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . println ("${ field . owner }. name Ġ= Ġ${ field . name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . owner Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ app Pkg /${ field . owner . substring ( field . owner . lastIndexOf ('/') Ġ+ Ġ 1 )}" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ // ĠĠĠ Ġprivate Ġval Ġ_ logger Ġ= ĠLogging . getLogger ( R Inline Transform :: class . java ) Ċ } Ċ