Skip to content

Commit

Permalink
Incremental annotation processing for Kotlin (#626)
Browse files Browse the repository at this point in the history
  • Loading branch information
technoir42 authored and hotchemi committed Jun 18, 2019
1 parent b4cc599 commit 37b3257
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import permissions.dispatcher.RuntimePermissions
import permissions.dispatcher.processor.impl.javaProcessorUnits
import permissions.dispatcher.processor.impl.kotlinProcessorUnits
import permissions.dispatcher.processor.util.findAndValidateProcessorUnit
import java.io.File
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.Filer
import javax.annotation.processing.ProcessingEnvironment
Expand All @@ -14,7 +13,6 @@ import javax.lang.model.element.Element
import javax.lang.model.element.TypeElement
import javax.lang.model.util.Elements
import javax.lang.model.util.Types
import javax.tools.Diagnostic
import kotlin.properties.Delegates

/** Element Utilities, obtained from the processing environment */
Expand All @@ -24,11 +22,6 @@ var TYPE_UTILS: Types by Delegates.notNull()

class PermissionsProcessor : AbstractProcessor() {

companion object {
// processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] returns generated/source/kaptKotlin/$sourceSetName
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
}

/* Processing Environment helpers */
private var filer: Filer by Delegates.notNull()

Expand Down Expand Up @@ -68,21 +61,9 @@ class PermissionsProcessor : AbstractProcessor() {
}

private fun processKotlin(element: Element, rpe: RuntimePermissionsElement, requestCodeProvider: RequestCodeProvider) {
// FIXME: weirdly under kaptKotlin files is not recognized as source file on AS or IntelliJ
// so as a workaround we generate .kt file in generated/source/kapt/$sourceSetName
// ref: https://github.com/hotchemi/PermissionsDispatcher/issues/320#issuecomment-316175775
val kaptGeneratedDirPath = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME]?.replace("kaptKotlin", "kapt")
?: run {
processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, "Can't find the target directory for generated Kotlin files.")
return
}
val kaptGeneratedDir = File(kaptGeneratedDirPath)
if (!kaptGeneratedDir.parentFile.exists()) {
kaptGeneratedDir.parentFile.mkdirs()
}
val processorUnit = findAndValidateProcessorUnit(kotlinProcessorUnits, element)
val kotlinFile = processorUnit.createFile(rpe, requestCodeProvider)
kotlinFile.writeTo(kaptGeneratedDir)
kotlinFile.writeTo(filer)
}

private fun processJava(element: Element, rpe: RuntimePermissionsElement, requestCodeProvider: RequestCodeProvider) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {

private fun createWithPermissionCheckFun(rpe: RuntimePermissionsElement, method: ExecutableElement): FunSpec {
val builder = FunSpec.builder(withPermissionCheckMethodName(method))
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.receiver(rpe.ktTypeName)
if (method.enclosingElement.isInternal) {
Expand Down Expand Up @@ -223,6 +224,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {

private fun createProceedPermissionRequestFun(rpe: RuntimePermissionsElement, needsMethod: ExecutableElement): FunSpec {
val builder = FunSpec.builder(needsMethod.proceedOnShowRationaleMethodName())
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.receiver(rpe.ktTypeName)
val targetParam = "this"
Expand All @@ -234,6 +236,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {

private fun createCancelPermissionRequestFun(rpe: RuntimePermissionsElement, onDenied: ExecutableElement, needsMethod: ExecutableElement): FunSpec {
return FunSpec.builder(needsMethod.cancelOnShowRationaleMethodName())
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.receiver(rpe.ktTypeName)
.addStatement("this.%N()", onDenied.simpleString())
Expand All @@ -255,6 +258,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {
val requestCodeParam = "requestCode"
val grantResultsParam = "grantResults"
val builder = FunSpec.builder("onActivityResult")
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.receiver(rpe.ktTypeName)
.addParameter(requestCodeParam, INT)
Expand Down Expand Up @@ -282,6 +286,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {
val requestCodeParam = "requestCode"
val grantResultsParam = "grantResults"
val builder = FunSpec.builder("onRequestPermissionsResult")
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.receiver(rpe.ktTypeName)
.addParameter(requestCodeParam, INT)
Expand All @@ -307,7 +312,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {


private fun addResultCaseBody(builder: FunSpec.Builder, needsMethod: ExecutableElement, rpe: RuntimePermissionsElement, grantResultsParam: String) {
val onDenied = rpe.findOnDeniedForNeeds(needsMethod)
val onDenied = rpe.findOnDeniedForNeeds(needsMethod)
val hasDenied = onDenied != null
val needsPermissionParameter = needsMethod.getAnnotation(NeedsPermission::class.java).value[0]
val permissionField = permissionFieldName(needsMethod)
Expand Down Expand Up @@ -418,6 +423,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {
val superInterfaceName = if (hasParameters) "GrantableRequest" else "PermissionRequest"

val builder = TypeSpec.classBuilder(permissionRequestTypeName(rpe, needsMethod))
.addOriginatingElement(rpe.element)
.addTypeVariables(rpe.ktTypeVariables)
.addSuperinterface(ClassName("permissions.dispatcher", superInterfaceName))
.addModifiers(KModifier.PRIVATE)
Expand Down Expand Up @@ -447,6 +453,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {

// Add proceed() override
val proceedFun = FunSpec.builder("proceed")
.addOriginatingElement(rpe.element)
.addModifiers(KModifier.OVERRIDE)
.addStatement("val target = %N.get() ?: return", propName)
val requestCodeField = requestCodeFieldName(needsMethod)
Expand All @@ -456,6 +463,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {

// Add cancel() override method
val cancelFun = FunSpec.builder("cancel")
.addOriginatingElement(rpe.element)
.addModifiers(KModifier.OVERRIDE)
val onDenied = rpe.findOnDeniedForNeeds(needsMethod)
if (onDenied != null) {
Expand All @@ -468,6 +476,7 @@ abstract class KotlinBaseProcessorUnit : KtProcessorUnit {
// For classes with additional parameters, add a "grant()" method
if (hasParameters) {
val grantFun = FunSpec.builder("grant")
.addOriginatingElement(rpe.element)
.addModifiers(KModifier.OVERRIDE)
.addStatement("val target = %N.get() ?: return", propName)

Expand Down

0 comments on commit 37b3257

Please sign in to comment.