package Ġcom . squareup . he pha est us . plugin Ċ Ċ import Ġcom . android . build . gradle . App Extension Ċ import Ġcom . android . build . gradle . App Plugin Ċ import Ġcom . android . build . gradle . Library Extension Ċ import Ġcom . android . build . gradle . Library Plugin Ċ import Ġcom . android . build . gradle . Test Extension Ċ import Ġcom . android . build . gradle . Tested Extension Ċ import Ġcom . android . build . gradle . api . Base Variant Ċ import Ġorg . gradle . api . Gradle Exception Ċ import Ġorg . gradle . api . Plugin Ċ import Ġorg . gradle . api . Project Ċ import Ġorg . gradle . api . plugins . Applied Plugin Ċ import Ġorg . gradle . api . plugins . PluginManager Ċ import Ġorg . gradle . api . provider . Provider Ċ import Ġorg . jetbrains . kotlin . gradle . internal . K apt Generate Stub s Task Ċ import Ġorg . jetbrains . kotlin . gradle . plugin . K apt Extension Ċ import Ġorg . jetbrains . kotlin . gradle . plugin . Kotlin Plugin Wrapper Ċ import Ġorg . jetbrains . kotlin . gradle . plugin . PLUGIN _ CLAS SPATH _ CONFIGURATION _ NAME Ċ import Ġorg . jetbrains . kotlin . gradle . tasks . Kotlin Compile Ċ import Ġjava . util . Locale . US Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ open Ġclass ĠHe pha est us Plugin Ġ: ĠPlugin < Project > Ġ{ ĊĠ Ġoverride Ġfun Ġapply ( project : ĠProject ) Ġ{ ĊĠĠĠ Ġval Ġonce Ġ= ĠAtomic Boolean () ĊĊĠĠĠ Ġfun ĠPlugin Manager . with Plugin Once ( ĊĠĠĠĠĠ Ġid : ĠString , ĊĠĠĠĠĠ Ġaction : Ġ( Applied Plugin ) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠ Ġwith Plugin ( id ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( once . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġaction ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠApply Ġthe ĠHe pha est us Ġplugin Ġafter Ġthe ĠKotlin Ġplugin Ġwas Ġapplied . ĠThere Ġcould Ġbe Ġa Ġtiming ĊĠĠĠ Ġ// Ġissue . ĠAlso Ġmake Ġsure Ġto Ġapply Ġit Ġonly Ġonce . ĠA Ġmodule Ġcould Ġaccidentally Ġapply Ġthe ĠJVM Ġand ĊĠĠĠ Ġ// ĠAndroid ĠKotlin Ġplugin . ĊĠĠĠ Ġproject . plugin Manager . with Plugin Once (" org . jetbrains . kotlin . android ") Ġ{ ĊĠĠĠĠĠ Ġreal Apply ( project , Ġtrue ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġproject . plugin Manager . with Plugin Once (" org . jetbrains . kotlin . jvm ") Ġ{ ĊĠĠĠĠĠ Ġreal Apply ( project , Ġfalse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġproject . after Evaluate Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! once . get ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠGradle Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" No Ġsupported Ġplugins Ġfor ĠHe pha est us Ġfound Ġon Ġproject Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"' ${ project . path }'. ĠOnly ĠAndroid Ġand ĠJava Ġmodules Ġare Ġsupported Ġfor Ġnow ." ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġreal Apply ( ĊĠĠĠ Ġproject : ĠProject , ĊĠĠĠ Ġis Android Project : ĠBoolean ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġdisable Incremental Kotlin Compilation ( project , Ġis Android Project ) ĊĠĠĠ Ġdisable Prec ise Java Tracking ( project ) ĊĊĠĠĠ Ġproject . plugin Manager . with Plugin (" org . jetbrains . kotlin . k apt ") Ġ{ ĊĠĠĠĠĠ Ġ// ĠThis Ġneeds Ġto Ġbe Ġdisabled , Ġotherwise Ġcompiler Ġplugins Ġfail Ġin Ġweird Ġways Ġwhen Ġgenerating Ġstub s . ĊĠĠĠĠĠ Ġproject . extensions . findBy Type ( K apt Extension :: class . java )?. correct Error Types Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġproject . dependencies . add (" api ", Ġ"$ GROUP : annotations :$ VERSION ") ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdisable Prec ise Java Tracking ( ĊĠĠĠ Ġproject : ĠProject ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġproject . tasks ĊĠĠĠĠĠĠĠ Ġ. with Type ( Kotlin Compile :: class . java ) ĊĠĠĠĠĠĠĠ Ġ. configure Each Ġ{ Ġcompile Task Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġcompile Task . do First Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDisable Ġprecise Ġjava Ġtracking Ġif Ġneeded . ĠNote Ġthat Ġthe Ġdo First () Ġaction Ġonly Ġruns ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġthe Ġtask Ġis Ġnot Ġup Ġto Ġdate . ĠThat 's Ġideal , Ġbecause Ġif Ġnothing Ġneeds Ġto Ġbe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcompiled , Ġthen Ġwe Ġdon 't Ġneed Ġto Ġdisable Ġthe Ġflag . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCheck Mixed Source Set ( compile Task . project , Ġcompile Task ). disable Prec ise Java Tracking IfNeeded () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompile Task . logger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" He pha est us : ĠUse Ġprecise Ġjava Ġtracking : Ġ${ compile Task . use Prec ise Java Tracking }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Opt In ( Experimental Std lib Api :: class ) ĊĠ Ġprivate Ġfun Ġdisable Incremental Kotlin Compilation ( ĊĠĠĠ Ġproject : ĠProject , ĊĠĠĠ Ġis Android Project : ĠBoolean ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġproject . tasks ĊĠĠĠĠĠĠĠ Ġ. with Type ( K apt Generate Stub s Task :: class . java ) ĊĠĠĠĠĠĠĠ Ġ. configure Each Ġ{ Ġstub s Task Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠDisable Ġincremental Ġcompilation Ġfor Ġthe Ġstub Ġgenerating Ġtask . ĠTrigger Ġthe Ġcompiler ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġplugin Ġif Ġany Ġdependencies Ġin Ġthe Ġcompile Ġclasspath Ġhave Ġchanged . ĠThis Ġwill Ġmake Ġsure ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġthat Ġwe Ġpick Ġup Ġany Ġchange Ġfrom Ġa Ġdependency Ġwhen Ġmerging Ġall Ġthe Ġclasses . ĠWithout ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġthis Ġworkaround Ġwe Ġcould Ġmake Ġchanges Ġin Ġany Ġlibrary , Ġbut Ġthese Ġchanges Ġwouldn 't Ġbe ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġcontributed Ġto Ġthe ĠD agger Ġgraph , Ġbecause Ġincremental Ġcompilation Ġtrick ed Ġus . ĊĠĠĠĠĠĠĠĠĠ Ġstub s Task . do First Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstub s Task . incremental Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstub s Task . logger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" He pha est us : ĠIncrement al Ġcompilation Ġenabled : Ġ${ stubs Task . incremental } Ġ( stub )" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠUse Ġthis Ġsignal Ġto Ġshare Ġstate Ġbetween ĠDisable Incremental Compilation Task Ġand Ġthe ĠKotlin ĊĠĠĠ Ġ// Ġcompile Ġtask . ĠIf Ġthe Ġplugin Ġclasspath Ġchanged , Ġthen ĠDisable Incremental Compilation Task Ġsets ĊĠĠĠ Ġ// Ġthe Ġsignal Ġto Ġfalse . ĊĠĠĠ Ġ@ Suppress (" Un stable Api Usage ") ĊĠĠĠ Ġval Ġincremental Signal Ġ= Ġproject . gradle . shared Services ĊĠĠĠĠĠĠĠ Ġ. register If Absent (" incremental Signal ", ĠIncrement al Signal :: class . java ) Ġ{ Ġ} ĊĊĠĠĠ Ġif Ġ( is Android Project ) Ġ{ ĊĠĠĠĠĠ Ġproject . android Variants Configure Ġ{ Ġvariant Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġcompile Task Name Ġ= Ġ" compile ${ variant . name . capitalize ( US )} Kotlin " ĊĠĠĠĠĠĠĠ Ġdisable Incremental Compilation Action ( project , Ġincremental Signal , Ġcompile Task Name ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġ// ĠThe ĠJava Ġplugin Ġhas Ġtwo ĠKotlin Ġtasks Ġwe Ġcare Ġabout : Ġcompile Kotlin Ġand Ġcompile Test Kotlin . ĊĠĠĠĠĠ Ġdisable Incremental Compilation Action ( project , Ġincremental Signal , Ġ" compile Kotlin ") ĊĠĠĠĠĠ Ġdisable Incremental Compilation Action ( project , Ġincremental Signal , Ġ" compile Test Kotlin ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġdisable Incremental Compilation Action ( ĊĠĠĠ Ġproject : ĠProject , ĊĠĠĠ Ġincremental Signal : ĠProvider < Incremental Signal >, ĊĠĠĠ Ġcompile Task Name : ĠString ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠDisable Ġincremental Ġcompilation , Ġif Ġthe Ġcompiler Ġplugin Ġdependency Ġisn 't Ġup - to - date . ĊĠĠĠ Ġ// ĠThis Ġwill Ġtrigger Ġa Ġfull Ġcompilation Ġof Ġa Ġmodule Ġusing ĠHe pha est us Ġeven Ġthough Ġits ĊĠĠĠ Ġ// Ġsource Ġfiles Ġmight Ġnot Ġhave Ġchanged . ĠThis Ġworkaround Ġis Ġnecessary , Ġotherwise ĊĠĠĠ Ġ// Ġincremental Ġbuilds Ġare Ġbroken . ĠSee Ġhttps :// yout rack . jetbrains . com / issue / KT - 3 8 5 7 0 ĊĠĠĠ Ġval Ġdisable Incremental Compilation Task Provider Ġ= Ġproject . tasks . register ( ĊĠĠĠĠĠĠĠ Ġcompile Task Name Ġ+ Ġ" Check Incremental Compilation He pha est us ", ĊĠĠĠĠĠĠĠ ĠDisable Incremental Compilation Task :: class . java ĊĠĠĠ Ġ) Ġ{ Ġtask Ġ-> ĊĠĠĠĠĠ Ġtask . plugin Classpath . from ( ĊĠĠĠĠĠĠĠĠĠ Ġproject . configurations . get ByName ( PLUGIN _ CLAS SPATH _ CONFIGURATION _ NAME ) ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġtask . incremental Signal . set ( incremental Signal ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġproject . tasks . named ( compile Task Name , ĠKotlin Compile :: class . java ) Ġ{ Ġcompile Task Ġ-> ĊĠĠĠĠĠ Ġcompile Task . depends On ( disable Incremental Compilation Task Provider ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠWe Ġavoid Ġa Ġreference Ġto Ġthe Ġproject Ġin Ġthe Ġdo First . ĊĠĠĠ Ġval Ġproject Path Ġ= Ġproject . path ĊĊĠĠĠ Ġ// ĠIf Ġwe Ġmerge Ġthe Ġblock Ġbelow Ġand Ġthe Ġblock Ġabove , Ġit Ġlooks Ġlike ĊĠĠĠ Ġ// Ġthe Ġkotlin Ġcompiler Ġis Ġgenerating Ġbyte Ġcode Ġfor ĊĠĠĠ Ġ// Ġdisable Incremental Compilation Task Provider Ġto Ġbe Ġvisible Ġfrom Ġthe Ġdo First Ġblock ĊĊĠĠĠ Ġproject . tasks . named ( compile Task Name , ĠKotlin Compile :: class . java ) Ġ{ Ġcompile Task Ġ-> ĊĠĠĠĠĠ Ġcompile Task . do First Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġsignal Ġis Ġset , Ġthen Ġthe Ġplugin Ġclasspath Ġchanged . ĠApply Ġthe Ġsetting Ġthat ĊĠĠĠĠĠĠĠ Ġ// ĠDisable Incremental Compilation Task Ġrequested . ĊĠĠĠĠĠĠĠ Ġval Ġincremental Ġ= Ġincremental Signal . get (). incremental [ project Path ] ĊĠĠĠĠĠĠĠ Ġif Ġ( incremental Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcompile Task . incremental Ġ= Ġincremental ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcompile Task . logger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" He pha est us : ĠIncrement al Ġcompilation Ġenabled : Ġ${ compile Task . incremental } Ġ( compile )" ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠReturns Ġall Ġvariants Ġincluding Ġthe Ġandroid Test Ġand Ġunit Ġtest Ġvariants . Ċ Ġ*/ Ċ fun ĠProject . android Variants (): ĠSet < Base Variant > Ġ{ ĊĠ Ġreturn Ġwhen Ġ( val Ġandroid Extension Ġ= Ġproject . extensions . find ByName (" android ")) Ġ{ ĊĠĠĠ Ġis ĠApp Extension Ġ-> Ġandroid Extension . application Variants Ġ+ Ġandroid Extension . test Variants Ġ+ ĊĠĠĠĠĠĠĠ Ġandroid Extension . unit Test Variants ĊĠĠĠ Ġis ĠLibrary Extension Ġ-> Ġandroid Extension . library Variants Ġ+ Ġandroid Extension . test Variants Ġ+ ĊĠĠĠĠĠĠĠ Ġandroid Extension . unit Test Variants ĊĠĠĠ Ġelse Ġ-> Ġthrow ĠGradle Exception (" Unknown ĠAndroid Ġmodule Ġtype Ġfor Ġproject Ġ${ project . path }") ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRuns Ġthe Ġgiven Ġ[ action ] Ġfor Ġeach ĠAndroid Ġvariant Ġincluding Ġandroid Test Ġand Ġunit Ġtest Ġvariants . Ċ Ġ*/ Ċ fun ĠProject . android Variants Configure ( action : Ġ( Base Variant ) Ġ-> ĠUnit ) Ġ{ ĊĠ Ġval Ġandroid Extension Ġ= Ġproject . extensions . find ByName (" android ") ĊĊĠ Ġif Ġ( android Extension Ġis ĠApp Extension ) Ġ{ ĊĠĠĠ Ġandroid Extension . application Variants . configure Each ( action ) ĊĠ Ġ} ĊĠ Ġif Ġ( android Extension Ġis ĠLibrary Extension ) Ġ{ ĊĠĠĠ Ġandroid Extension . library Variants . configure Each ( action ) ĊĠ Ġ} ĊĠ Ġif Ġ( android Extension Ġis ĠTest Extension ) Ġ{ ĊĠĠĠ Ġandroid Extension . application Variants . configure Each ( action ) ĊĠ Ġ} ĊĠ Ġif Ġ( android Extension Ġis ĠTested Extension ) Ġ{ ĊĠĠĠ Ġandroid Extension . unit Test Variants . configure Each ( action ) ĊĠĠĠ Ġandroid Extension . test Variants . configure Each ( action ) ĊĠ Ġ} Ċ } Ċ Ċ @ Opt In ( Experimental Std lib Api :: class ) Ċ fun ĠCollection < Base Variant >. find Variant For Compile Task ( ĊĠ Ġcompile Task : ĠKotlin Compile Ċ ): ĠBase Variant Ġ= Ġthis ĊĠĠĠ Ġ. filter Ġ{ Ġvariant Ġ-> ĊĠĠĠĠĠ Ġcompile Task . name . contains ( variant . name . capitalize ( US )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ. max By Ġ{ ĊĠĠĠĠĠ Ġ// ĠThe Ġfilter Ġabove Ġstill Ġreturns Ġmultiple Ġvariants , Ġe . g . Ġfor Ġthe ĊĠĠĠĠĠ Ġ// Ġ" compile Debug UnitTest Kotlin " Ġtask Ġit Ġreturns Ġthe Ġvariants Ġ" debug " Ġand Ġ" debug UnitTest ". ĊĠĠĠĠĠ Ġ// ĠIn Ġthis Ġcase Ġprefer Ġthe Ġvariant Ġwith Ġthe Ġlongest Ġmatching Ġname , Ġbecause Ġthat 's Ġthe Ġmore ĊĠĠĠĠĠ Ġ// Ġexplicit Ġvariant Ġthat Ġwe Ġwant . ĊĠĠĠĠĠ Ġit . name . length ĊĠĠĠ Ġ} !! Ċ Ċ val ĠProject . is Kotlin Jvm Project : ĠBoolean ĊĠ Ġget () Ġ= Ġplugins . has Plugin ( Kotlin Plugin Wrapper :: class . java ) Ċ Ċ val ĠProject . is Android Project : ĠBoolean ĊĠ Ġget () Ġ= ĠA GP _ ON _ CLAS SPATH Ġ&& ĊĠĠĠĠĠ Ġ( plugins . has Plugin ( App Plugin :: class . java ) Ġ|| Ġplugins . has Plugin ( Library Plugin :: class . java )) Ċ Ċ @ Suppress (" S ENSE LESS _ COMP AR IS ON ") Ċ private Ġval ĠA GP _ ON _ CLAS SPATH Ġ= Ġtry Ġ{ ĊĠ ĠClass . forName (" com . android . build . gradle . App Plugin ") Ġ!= Ġnull Ċ } Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠ Ġfalse Ċ } Ċ