Skip to content

Commit

Permalink
Add protected state setter
Browse files Browse the repository at this point in the history
  • Loading branch information
Pablo Orgaz committed Aug 3, 2018
1 parent 81819e0 commit 0fac178
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 42 deletions.
5 changes: 4 additions & 1 deletion mini-common/src/main/java/mini/Store.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ abstract class Store<S : Any> {
val properties: MutableMap<String, Any?> = HashMap()

private var _state: S? = null
val state: S
var state: S
get() {
if (_state == null) _state = initialState()
return _state!!
}
protected set(value) {
setStateInternal(value)
}

private val observers: MutableList<StoreObserver<S>> = ArrayList()
private val processor: PublishProcessor<S> = PublishProcessor.create()
Expand Down
79 changes: 39 additions & 40 deletions mini-processor/src/main/java/mini/processor/ActionReducerModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ class ActionReducerModel(private val reducerFunctions: List<ReducerFuncModel>) {

init {
stores = reducerFunctions
.distinctBy { it.storeElement.qualifiedName() }
.map {
StoreModel(
fieldName = it.storeFieldName,
element = it.storeElement)
}
.distinctBy { it.storeElement.qualifiedName() }
.map {
StoreModel(
fieldName = it.storeFieldName,
element = it.storeElement)
}

reducerParameters = reducerFunctions.map { it.tag }
.map { ReducerFunctionParameterModel(it.asElement()) }
.distinctBy { it.element.qualifiedName() }
.map { ReducerFunctionParameterModel(it.asElement()) }
.distinctBy { it.element.qualifiedName() }

tags = reducerParameters.map { it.tags }
.flatten()
.distinctBy { it.typeMirror.qualifiedName() }
.flatten()
.distinctBy { it.typeMirror.qualifiedName() }

actionToFunctionMap = reducerParameters.map { parameterModel ->
parameterModel to reducerFunctions
.filter { it.tag.qualifiedName() in parameterModel.tags.map { it.typeMirror.qualifiedName() } }
.sortedBy { it.priority }
.filter { it.tag.qualifiedName() in parameterModel.tags.map { it.typeMirror.qualifiedName() } }
.sortedBy { it.priority }
}.toMap().toSortedMap(Comparator { a, b ->
val aType = a.element.asType()
val bType = b.element.asType()
Expand All @@ -61,42 +61,43 @@ class ActionReducerModel(private val reducerFunctions: List<ReducerFuncModel>) {
val builder = FileSpec.builder(MINI_COMMON_PACKAGE_NAME, ACTION_REDUCER_CLASS_NAME)
//Start generating file
val kotlinFile = builder
.addType(TypeSpec.classBuilder(ACTION_REDUCER_CLASS_NAME)
.addSuperinterface(ClassName(MINI_COMMON_PACKAGE_NAME, ACTION_REDUCER_INTERFACE))
.addMainConstructor()
.addStoreProperties()
.addDispatcherFunction()
.build())
.build()
.addType(TypeSpec.classBuilder(ACTION_REDUCER_CLASS_NAME)
.addSuperinterface(ClassName(MINI_COMMON_PACKAGE_NAME, ACTION_REDUCER_INTERFACE))
.addMainConstructor()
.addStoreProperties()
.addDispatcherFunction()
.build())
.build()

val kotlinFileObject = env.filer.createResource(StandardLocation.SOURCE_OUTPUT,
MINI_PROCESSOR_PACKAGE_NAME, "${kotlinFile.name}.kt")
MINI_PROCESSOR_PACKAGE_NAME, "${kotlinFile.name}.kt")
val openWriter = kotlinFileObject.openWriter()
kotlinFile.writeTo(openWriter)
openWriter.close()
}

private fun TypeSpec.Builder.addMainConstructor(): TypeSpec.Builder {
return primaryConstructor(FunSpec.constructorBuilder()
.addParameter("stores", getStoreMapType())
.build())
.addParameter("stores", getStoreMapType())
.build())
}

private fun TypeSpec.Builder.addStoreProperties(): TypeSpec.Builder {
stores.forEach { storeModel ->
val typeName = storeModel.element.asType().asTypeName()
addProperty(PropertySpec.builder(storeModel.fieldName, typeName)
.addModifiers(KModifier.PRIVATE)
.initializer(CodeBlock.of("stores.get(%T::class.java) as %T", typeName, typeName))
.build()
.addModifiers(KModifier.PRIVATE)
.initializer(CodeBlock.of("stores.get(%T::class.java) as %T", typeName, typeName))
.build()
)
}
return this
}

private fun TypeSpec.Builder.addDispatcherFunction(): TypeSpec.Builder {
val reduceBuilder = with(FunSpec.builder("reduce")) {
addParameters(listOf("action" to Action::class).map { ParameterSpec.builder(it.first, it.second).build() })

addParameter(ParameterSpec.builder("action", Action::class).build())
addModifiers(KModifier.OVERRIDE)

addStatement("when (action) {%>")
Expand All @@ -113,19 +114,17 @@ class ActionReducerModel(private val reducerFunctions: List<ReducerFuncModel>) {
reducers.forEach { reducer ->
val storeFieldName = reducer.storeFieldName

fun callString(): CodeBlock {
return if (reducer.hasStateParameter) {
CodeBlock.of("action, $storeFieldName.state")
} else {
CodeBlock.of("action")
}
val callString = if (reducer.hasStateParameter) {
CodeBlock.of("action, $storeFieldName.state")
} else {
CodeBlock.of("action")
}

addCode(CodeBlock.builder()
.add("$storeFieldName.setStateInternal(")
.add("$storeFieldName.${reducer.funcName}(${callString()})")
.add(")\n")
.build())
.add("$storeFieldName.setStateInternal(")
.add("$storeFieldName.${reducer.funcName}($callString)")
.add(")\n")
.build())
}
addStatement("%<}")
}
Expand Down Expand Up @@ -158,8 +157,8 @@ class ActionReducerModel(private val reducerFunctions: List<ReducerFuncModel>) {

@TestOnly
fun generateActionReducer(className: String, packageName: String) = TypeSpec.classBuilder(className)
.addSuperinterface(ClassName(packageName, ACTION_REDUCER_INTERFACE))
.addMainConstructor()
.addStoreProperties()
.addDispatcherFunction()
.addSuperinterface(ClassName(packageName, ACTION_REDUCER_INTERFACE))
.addMainConstructor()
.addStoreProperties()
.addDispatcherFunction()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.TypeElement

@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("org.kotlin.annotationProcessor.reducer")
@SupportedOptions(MiniProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME)
class MiniProcessor : AbstractProcessor() {

Expand Down

0 comments on commit 0fac178

Please sign in to comment.