Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

Commit

Permalink
feat: Generating extra class for Widget and Actions registration (#876)
Browse files Browse the repository at this point in the history
* feat: Created generated class for Widgets and Actions

* Remove unused import

Co-authored-by: Túlio Magalhães <[email protected]>
  • Loading branch information
tuliopereirazup and tuliomagalhaes authored Sep 4, 2020
1 parent 72fee80 commit baefa4d
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ class InternalWidgetFactoryProcessor(

val typeSpec = TypeSpec.objectBuilder(className)
.addModifiers(KModifier.INTERNAL)
.addFunction(beagleSetupRegisteredWidgetGenerator.generate(
roundEnvironment = roundEnvironment,
isOverride = false
))
.addFunction(beagleSetupRegisteredWidgetGenerator.generate(roundEnvironment))
.build()

val beagleSetupFile = FileSpec.builder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ import javax.annotation.processing.RoundEnvironment

class BeagleSetupProcessor(
private val processingEnv: ProcessingEnvironment,
private val beagleSetupRegisteredWidgetGenerator: BeagleSetupRegisteredWidgetGenerator =
BeagleSetupRegisteredWidgetGenerator(),
private val registeredActionGenerator: RegisteredActionGenerator = RegisteredActionGenerator(),
private val registerWidgetProcessorProcessor: RegisterWidgetProcessorProcessor =
RegisterWidgetProcessorProcessor(processingEnv),
private val registerActionProcessorProcessor: RegisterActionProcessorProcessor =
RegisterActionProcessorProcessor(processingEnv),
private val beagleSetupPropertyGenerator: BeagleSetupPropertyGenerator =
BeagleSetupPropertyGenerator(processingEnv),
private val registerAnnotationProcessor: RegisterControllerProcessor =
Expand All @@ -62,8 +63,8 @@ class BeagleSetupProcessor(
val typeSpec = TypeSpec.classBuilder(beagleSetupClassName)
.addModifiers(KModifier.PUBLIC, KModifier.FINAL)
.addSuperinterface(ClassName(BEAGLE_SDK.packageName, BEAGLE_SDK.className))
.addFunction(beagleSetupRegisteredWidgetGenerator.generate(roundEnvironment))
.addFunction(registeredActionGenerator.generate(roundEnvironment))
.addFunction(registerWidgetProcessorProcessor.createRegisteredWidgetsFunction())
.addFunction(registerActionProcessorProcessor.createRegisteredActionsFunction())


val beagleSetupFile = FileSpec.builder(
Expand All @@ -85,6 +86,8 @@ class BeagleSetupProcessor(

var property = properties[propertyIndex]

registerWidgetProcessorProcessor.process(basePackageName, roundEnvironment)
registerActionProcessorProcessor.process(basePackageName, roundEnvironment)
registerAnnotationProcessor.process(basePackageName, roundEnvironment, property.initializer.toString())

val defaultActivity = registerAnnotationProcessor.defaultActivityRegistered
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
*
* 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 br.com.zup.beagle.android.compiler

import br.com.zup.beagle.compiler.REGISTERED_ACTIONS
import br.com.zup.beagle.compiler.RegisteredActionGenerator
import br.com.zup.beagle.compiler.error
import br.com.zup.beagle.widget.Widget
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.RoundEnvironment

const val REGISTERED_ACTIONS_GENERATED = "RegisteredActions"

class RegisterActionProcessorProcessor(
private val processingEnv: ProcessingEnvironment,
private val registeredActionGenerator: RegisteredActionGenerator =
RegisteredActionGenerator()
) {

fun process(packageName: String, roundEnvironment: RoundEnvironment) {
val typeSpec = TypeSpec.classBuilder(REGISTERED_ACTIONS_GENERATED)
.addModifiers(KModifier.PUBLIC, KModifier.FINAL)
.addFunction(createRegisteredActionsFunctionInternal(roundEnvironment))
.build()

try {
FileSpec.builder(packageName, REGISTERED_ACTIONS_GENERATED)
.addImport(Widget::class, "")
.addAnnotation(
AnnotationSpec.builder(Suppress::class.java)
.addMember("%S", "UNCHECKED_CAST")
.build()
)
.addType(typeSpec)
.build()
.writeTo(processingEnv.filer)
} catch (e: IOException) {
val errorMessage = "Error when trying to generate code.\n${e.message!!}"
processingEnv.messager.error(errorMessage)
}
}

private fun createRegisteredActionsFunctionInternal(roundEnvironment: RoundEnvironment): FunSpec {
return registeredActionGenerator.generate(roundEnvironment)
}

fun createRegisteredActionsFunction(): FunSpec {
return registeredActionGenerator.createFuncSpec()
.addModifiers(KModifier.OVERRIDE)
.addStatement("return $REGISTERED_ACTIONS_GENERATED().$REGISTERED_ACTIONS()")
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
*
* 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 br.com.zup.beagle.android.compiler

import br.com.zup.beagle.compiler.BeagleSetupRegisteredWidgetGenerator
import br.com.zup.beagle.compiler.REGISTERED_WIDGETS
import br.com.zup.beagle.compiler.error
import br.com.zup.beagle.widget.Widget
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.RoundEnvironment

const val REGISTERED_WIDGETS_GENERATED = "RegisteredWidgets"

class RegisterWidgetProcessorProcessor(
private val processingEnv: ProcessingEnvironment,
private val beagleSetupRegisteredWidgetGenerator: BeagleSetupRegisteredWidgetGenerator =
BeagleSetupRegisteredWidgetGenerator()
) {

fun process(packageName: String, roundEnvironment: RoundEnvironment) {
val typeSpec = TypeSpec.classBuilder(REGISTERED_WIDGETS_GENERATED)
.addModifiers(KModifier.PUBLIC, KModifier.FINAL)
.addFunction(createRegisteredWidgetsFunctionInternal(roundEnvironment))
.build()

try {
FileSpec.builder(packageName, REGISTERED_WIDGETS_GENERATED)
.addImport(Widget::class, "")
.addAnnotation(
AnnotationSpec.builder(Suppress::class.java)
.addMember("%S", "UNCHECKED_CAST")
.build()
)
.addType(typeSpec)
.build()
.writeTo(processingEnv.filer)
} catch (e: IOException) {
val errorMessage = "Error when trying to generate code.\n${e.message!!}"
processingEnv.messager.error(errorMessage)
}
}

private fun createRegisteredWidgetsFunctionInternal(roundEnvironment: RoundEnvironment): FunSpec {
return beagleSetupRegisteredWidgetGenerator.generate(roundEnvironment)
}

fun createRegisteredWidgetsFunction(): FunSpec {
return beagleSetupRegisteredWidgetGenerator.createFuncSpec()
.addModifiers(KModifier.OVERRIDE)
.addStatement("return $REGISTERED_WIDGETS_GENERATED().$REGISTERED_WIDGETS()")
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,43 @@ package br.com.zup.beagle.compiler
import br.com.zup.beagle.annotation.RegisterWidget
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.asClassName
import javax.annotation.processing.RoundEnvironment

const val REGISTERED_WIDGETS = "registeredWidgets"

class BeagleSetupRegisteredWidgetGenerator {

fun generate(roundEnvironment: RoundEnvironment, isOverride: Boolean = true): FunSpec {
fun generate(roundEnvironment: RoundEnvironment): FunSpec {
val classValues = StringBuilder()
val registerWidgetAnnotatedClasses = roundEnvironment.getElementsAnnotatedWith(RegisterWidget::class.java)
val listReturnType = List::class.asClassName().parameterizedBy(
Class::class.asClassName().parameterizedBy(
ClassName(WIDGET_VIEW.packageName, WIDGET_VIEW.className)
)
)

registerWidgetAnnotatedClasses.forEachIndexed { index, element ->
classValues.append("\t${element}::class.java as Class<WidgetView>")
if (index < registerWidgetAnnotatedClasses.size - 1) {
classValues.append(",\n")
}
}
val spec = FunSpec.builder("registeredWidgets")

if (isOverride)
spec.addModifiers(KModifier.OVERRIDE)

return spec
.returns(listReturnType)
return createFuncSpec()
.addCode("""
|val registeredWidgets = listOf<Class<WidgetView>>(
|val $REGISTERED_WIDGETS = listOf<Class<WidgetView>>(
| $classValues
|)
|""".trimMargin())
.addStatement("return registeredWidgets")
.addStatement("return $REGISTERED_WIDGETS")
.build()
}

fun createFuncSpec(): FunSpec.Builder {
val listReturnType = List::class.asClassName().parameterizedBy(
Class::class.asClassName().parameterizedBy(
ClassName(WIDGET_VIEW.packageName, WIDGET_VIEW.className)
)
)

return FunSpec.builder(REGISTERED_WIDGETS)
.returns(listReturnType)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,35 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.asClassName
import javax.annotation.processing.RoundEnvironment

const val REGISTERED_ACTIONS = "registeredActions"

class RegisteredActionGenerator {

fun generate(roundEnvironment: RoundEnvironment): FunSpec {
val registerAnnotatedClasses = roundEnvironment.getElementsAnnotatedWith(RegisterAction::class.java)
val listReturnType = List::class.asClassName().parameterizedBy(
Class::class.asClassName().parameterizedBy(
ClassName(ANDROID_ACTION.packageName, ANDROID_ACTION.className)
)
)

val classValues = registerAnnotatedClasses.joinToString(",\n") { element ->
"\t${element}::class.java as Class<Action>"
}

return FunSpec.builder("registeredActions")
.addModifiers(KModifier.OVERRIDE)
.returns(listReturnType)
return createFuncSpec()
.addCode("""
|val registeredActions = listOf<Class<Action>>(
|val $REGISTERED_ACTIONS = listOf<Class<Action>>(
| $classValues
|)
|""".trimMargin())
.addStatement("return registeredActions")
.addStatement("return $REGISTERED_ACTIONS")
.build()
}

fun createFuncSpec(): FunSpec.Builder {
val listReturnType = List::class.asClassName().parameterizedBy(
Class::class.asClassName().parameterizedBy(
ClassName(ANDROID_ACTION.packageName, ANDROID_ACTION.className)
)
)

return FunSpec.builder(REGISTERED_ACTIONS)
.returns(listReturnType)
}
}

0 comments on commit baefa4d

Please sign in to comment.