/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 8 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 . android . build . gradle . internal . tasks Ċ Ċ import Ġcom . android . Sdk Constants Ċ import Ġcom . android . build . gradle . internal . worker actions . Worker Action Service Registry Ċ import Ġcom . android . build . gradle . internal . worker actions . Worker Action Service Registry . Service Key Ċ import Ġcom . android . builder . dex ing . Class File Input Ċ import Ġcom . android . ide . common . workers . Worker Executor Facade Ċ import Ġcom . google . common . collect . Maps Ċ import Ġorg . gradle . api . artifacts . Artifact Collection Ċ import Ġjava . io . File Ċ import Ġjava . io . Serializable Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . zip . Zip File Ċ import Ġjavax . inject . Inject Ċ import Ġkotlin . streams . toList Ċ Ċ /** Ċ Ġ* ĠA Ġclass Ġthat Ġchecks Ġfor Ġduplicate Ġclasses Ġwithin Ġan ĠArtifact Collection . ĠClasses Ġare Ġassumed Ġto Ġbe Ċ Ġ* Ġduplicate Ġif Ġthey Ġhave Ġthe Ġsame Ġname Ġand Ġthey Ġare Ġposition ed Ġwithin Ġthe Ġsame Ġpackage Ġ( this Ġis Ċ Ġ* Ġpossible Ġif Ġthey Ġare Ġin Ġdifferent Ġartifacts ). Ċ Ġ*/ Ċ class ĠCheck Duplicate Classes Delegate ( private Ġval Ġclasses Artifacts : ĠArtifact Collection ) Ġ{ ĊĊĠĠĠ Ġclass ĠArtifact Classes Map Ġ: ĠConcurrent HashMap < String , ĠList < String >>() ĊĊĠĠĠ Ġdata Ġclass ĠArtifact Classes Key ( private Ġval Ġname : ĠString ) Ġ: ĠService Key < Artifact Classes Map > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġtype Ġ= ĠArtifact Classes Map :: class . java ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrun ( workers : ĠWorker Executor Facade ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġartifact Classes Ġ= ĠArtifact Classes Map () ĊĊĠĠĠĠĠĠĠ ĠWorker Action Service Registry ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. Manager ( artifact Classes , ĠArtifact Classes Key (" artifact Classes ${ hashCode ()} ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. use Ġ{ Ġkey Manager Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġworkers . use Ġ{ Ġfac ade Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclasses Artifacts . artifacts . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfac ade . submit ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠExtract Classes Runnable :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠExtract Classes Params ( it . id . displayName , Ġit . file , Ġkey Manager . key !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfac ade . await () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfac ade . submit ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCheck Duplicates Runnable :: class . java , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCheck Duplicates Params ( key Manager . key !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfac ade . await () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġdata Ġclass ĠExtract Classes Params ( ĊĠĠĠ Ġval Ġartifact Name : ĠString , ĊĠĠĠ Ġval Ġartifact File : ĠFile , ĊĠĠĠ Ġval Ġservice Key : ĠService Key < Check Duplicate Classes Delegate . Artifact Classes Map > Ċ ) Ġ: ĠSerializable Ċ Ċ private Ġclass ĠExtract Classes Runnable Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġparams : ĠExtract Classes Params ) Ġ: ĠRunnable Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= ĠWorker Action Service Registry . INSTANCE . getService ( params . service Key ). service ĊĠĠĠĠĠĠĠ Ġmap [ params . artifact Name ] Ġ= Ġextract Classes ( params . artifact File ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġdata Ġclass ĠCheck Duplicates Params ( ĊĠĠĠ Ġval Ġservice Key : ĠService Key < Check Duplicate Classes Delegate . Artifact Classes Map >): ĠSerializable Ċ Ċ private Ġconst Ġval ĠRE COMM END ATION Ġ= ĊĠĠĠ Ġ" Go Ġto Ġthe Ġdocumentation Ġto Ġlearn Ġhow Ġto Ġ< a Ġhref =\" d . android . com / r / tools / classpath - sync - errors \"> Fix Ġdependency Ġresolution Ġerrors </ a > ." Ċ Ċ private Ġfun Ġduplicate Class Message ( className : ĠString , Ġartifact Names : ĠList < String >): ĠString Ġ{ ĊĠĠĠ Ġval Ġsorted Ġ= Ġartifact Names . sorted () ĊĠĠĠ Ġval Ġmodules Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġartifact Names . size Ġ== Ġ 2 Ġ-> Ġ" modules Ġ${ sorted [ 0 ]} Ġand Ġ${ sorted [ 1 ]}" ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Ġ= Ġsorted . last () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" the Ġfollowing Ġmodules : Ġ${ sorted . drop Last ( 1 ). join ToString (", Ġ" )} Ġand Ġ$ last " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġ" Duplicate Ġclass Ġ$ className Ġfound Ġin Ġ$ modules " Ċ } Ċ Ċ private Ġclass ĠCheck Duplicates Runnable Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġparams : ĠCheck Duplicates Params ) Ġ: ĠRunnable Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= ĠWorker Action Service Registry . INSTANCE . getService ( params . service Key ). service ĊĠĠĠĠĠĠĠ Ġval ĠmaxSize Ġ= Ġmap . map Ġ{ Ġit . value . size Ġ}. sum () ĊĠĠĠĠĠĠĠ Ġval Ġclasses Ġ= ĠMaps . new HashMap With Expected Size < String , ĠMutable List < String >>( maxSize ) ĊĊĠĠĠĠĠĠĠ Ġmap . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġartifact Name Ġ= Ġit . key ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . value . forEach Ġ{ ĠclassName Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclasses . get Or Put ( className ) Ġ{ Ġmutable ListOf () Ġ}. add ( artifact Name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġduplicates Map Ġ= Ġclasses . filter Ġ{ Ġit . value . size Ġ> Ġ 1 Ġ}. to Sorted Map () ĊĠĠĠĠĠĠĠ Ġif Ġ(! duplicates Map . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġline Separator Ġ= ĠSystem . line Separator () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġduplicate Messages Ġ= Ġduplicates Map ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġduplicate Class Message ( it . key , Ġit . value ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. join ToString ( line Separator ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException ("$ duplicate Messages $ line Separator $ line Separator $ RE COMM END ATION ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġextract Classes ( jar File : ĠFile ): ĠList < String > Ġ= ĠZip File ( jar File ). use Ġ{ ĊĠĠĠ Ġreturn Ġit . stream () ĊĠĠĠ Ġ. filter Ġ{ ĠClass File Input . CLASS _ MATCH ER . test ( it . name ) Ġ} ĊĠĠĠ Ġ. map Ġ{ Ġit . name . replace ('/', Ġ'. '). drop Last ( Sdk Constants . DOT _ CLASS . length ) Ġ} ĊĠĠĠ Ġ. toList () Ċ } Ċ