Skip to content

Commit

Permalink
Optimize generated code (#985)
Browse files Browse the repository at this point in the history
* Order generated kotlin extensions, options to reduce generated code size

* update approach to excluding bitset lines

* update test sources

* fixes

* formatting

* add changelog breaking note
  • Loading branch information
elihart authored Jun 1, 2020
1 parent 6b2c340 commit 4a2c055
Show file tree
Hide file tree
Showing 35 changed files with 209 additions and 226 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 4.0.0-beta3 (May 27, 2020)
- Sort functions in generated kotlin extension function files deterministically to prevent generated sources from changing
- Avoid generating bitset checks in models when not needed
- Add options to skip generation of functions for getters, reset, and method overloads to reduce generated code

New annotation processor options are:
- epoxyDisableGenerateOverloads
- epoxyDisableGenerateGetters
- epoxyDisableGenerateReset

These can also be controlled (and overridden) on a per package level with the `PackageModelViewConfig` package annotation.

# 4.0.0-beta1 (May 22, 2020)
- Support for incremental annotation processing as an Aggregating processor (#972)
- Removed Litho support
Expand All @@ -19,6 +31,16 @@ Parallel processing can greatly speed up processing time (moreso than the increm
Please report any issues or crashes that you notice.
(We are currently using parallel mode in our large project at Airbnb with no problems.)

## Breaking
In order to enable incremental annotation processing a change had to be made in how the processor of
`@AutoModel` annotations work. If you use `@AutoModel` in an EpoxyController the annotated Model types
must be either declared in a different module from the EpoxyController, or in the same module in the same java package.

Also make sure you have kapt error types enabled.

However, generally `@AutoModel` is considered legacy and is not recommended. It is a relic of Java Epoxy usage
and instead the current best practice is to use Kotlin with the Kotlin model extension functions to build models.

# 3.11.0 (May 20, 2020)
- Introduce partial impression visibility states (#973)
- Fix sticky header crash (#976)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,47 @@
* Suffix, which will be appended to generated model's names. "Model_" is a default value.
*/
String generatedModelSuffix() default "Model_";

/**
* Controls whether "builder" setter functions that returns the model type will be duplicated
* from super model classes with the function return type updated to use the generated model name.
* This helps make all setters (such as id(...) ) return the same generated model so they can be
* chained in a builder pattern. This is mainly intended for Java usage and is generally
* unnecessary when using models in kotlin, especially if the generated kotlin model
* build extension functions are used. Disabling this can greatly reduce the number of
* methods generated on models.
*
* Default is false. This may also be set project wide with an annotation processor option.
*/
Option disableGenerateBuilderOverloads() default Option.Default;

/**
* Controls whether getter functions (that return the value of each attribute) are generated
* on models.
*
* Disabling this can greatly reduce the number of methods generated on models.
*
* Default is false. This may also be set project wide with an annotation processor option.
*/
Option disableGenerateGetters() default Option.Default;

/**
* Controls whether the "reset" function (that clears all attribute values) are generated
* on models. This function is generally legacy and is not recommended to be used with the modern
* immutable model approach of EpoxyControllers.
*
* Disabling this reduces the amount of generated code.
*
* Default is false. This may also be set project wide with an annotation processor option.
*/
Option disableGenerateReset() default Option.Default;

/**
* Enable or Disable an option, or inherit the default.
*/
enum Option {
Default,
Enabled,
Disabled
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ public class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> imple

private OnModelVisibilityChangedListener<AllTypesModelViewModel_, AllTypesModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;

/**
* Bitset index: 0 */
private boolean booleanValue_Boolean = false;

/**
Expand All @@ -52,12 +50,8 @@ public class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> imple
@NonNull
private Double boxedDoubleValue_Double;

/**
* Bitset index: 4 */
private double doubleValue_Double = 0.0d;

/**
* Bitset index: 5 */
@DrawableRes
private int drawableRes_Int = 0;

Expand All @@ -66,17 +60,13 @@ public class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> imple
@NonNull
private List<? extends EpoxyModel<?>> epoxyModelList_List;

/**
* Bitset index: 7 */
private int intValue_Int = 0;

/**
* Bitset index: 8 */
@NonNull
private Integer boxedIntValue_Integer;

/**
* Bitset index: 9 */
private long longValue_Long = 0L;

/**
Expand All @@ -89,8 +79,6 @@ public class AllTypesModelViewModel_ extends EpoxyModel<AllTypesModelView> imple
@NonNull
private View.OnClickListener onClickListener_OnClickListener;

/**
* Bitset index: 12 */
@RawRes
private int rawRes_Int = 0;

Expand Down Expand Up @@ -326,7 +314,6 @@ public AllTypesModelViewModel_ onVisibilityChanged(
* @see AllTypesModelView#setBooleanValue(boolean)
*/
public AllTypesModelViewModel_ booleanValue(boolean booleanValue) {
assignedAttributes_epoxyGeneratedModel.set(0);
onMutation();
this.booleanValue_Boolean = booleanValue;
return this;
Expand Down Expand Up @@ -402,7 +389,6 @@ public Double boxedDoubleValue() {
* @see AllTypesModelView#setDoubleValue(double)
*/
public AllTypesModelViewModel_ doubleValue(double doubleValue) {
assignedAttributes_epoxyGeneratedModel.set(4);
onMutation();
this.doubleValue_Double = doubleValue;
return this;
Expand All @@ -418,7 +404,6 @@ public double doubleValue() {
* @see AllTypesModelView#setDrawableRes(int)
*/
public AllTypesModelViewModel_ drawableRes(@DrawableRes int drawableRes) {
assignedAttributes_epoxyGeneratedModel.set(5);
onMutation();
this.drawableRes_Int = drawableRes;
return this;
Expand Down Expand Up @@ -456,7 +441,6 @@ public List<? extends EpoxyModel<?>> epoxyModelList() {
* @see AllTypesModelView#setIntValue(int)
*/
public AllTypesModelViewModel_ intValue(int intValue) {
assignedAttributes_epoxyGeneratedModel.set(7);
onMutation();
this.intValue_Int = intValue;
return this;
Expand Down Expand Up @@ -492,7 +476,6 @@ public Integer boxedIntValue() {
* @see AllTypesModelView#setLongValue(long)
*/
public AllTypesModelViewModel_ longValue(long longValue) {
assignedAttributes_epoxyGeneratedModel.set(9);
onMutation();
this.longValue_Long = longValue;
return this;
Expand Down Expand Up @@ -563,7 +546,6 @@ public View.OnClickListener onClickListener() {
* @see AllTypesModelView#setRawRes(int)
*/
public AllTypesModelViewModel_ rawRes(@RawRes int rawRes) {
assignedAttributes_epoxyGeneratedModel.set(12);
onMutation();
this.rawRes_Int = rawRes;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.util.BitSet;

/**
* Generated file. Do not modify! */
public class CallbackPropModelViewModel_ extends EpoxyModel<CallbackPropModelView> implements GeneratedModel<CallbackPropModelView>, CallbackPropModelViewModelBuilder {
private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(1);

private OnModelBoundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelBoundListener_epoxyGeneratedModel;

private OnModelUnboundListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelUnboundListener_epoxyGeneratedModel;
Expand All @@ -23,8 +20,6 @@ public class CallbackPropModelViewModel_ extends EpoxyModel<CallbackPropModelVie

private OnModelVisibilityChangedListener<CallbackPropModelViewModel_, CallbackPropModelView> onModelVisibilityChangedListener_epoxyGeneratedModel;

/**
* Bitset index: 0 */
@Nullable
private View.OnClickListener onClickListener_OnClickListener = (View.OnClickListener) null;

Expand Down Expand Up @@ -152,7 +147,6 @@ public CallbackPropModelViewModel_ onVisibilityChanged(
* Set a click listener that will provide the parent view, model, and adapter position of the clicked view. This will clear the normal View.OnClickListener if one has been set */
public CallbackPropModelViewModel_ onClickListener(
@Nullable final OnModelClickListener<CallbackPropModelViewModel_, CallbackPropModelView> onClickListener) {
assignedAttributes_epoxyGeneratedModel.set(0);
onMutation();
if (onClickListener == null) {
this.onClickListener_OnClickListener = null;
Expand All @@ -170,7 +164,6 @@ public CallbackPropModelViewModel_ onClickListener(
*/
public CallbackPropModelViewModel_ onClickListener(
@Nullable View.OnClickListener onClickListener) {
assignedAttributes_epoxyGeneratedModel.set(0);
onMutation();
this.onClickListener_OnClickListener = onClickListener;
return this;
Expand Down Expand Up @@ -261,7 +254,6 @@ public CallbackPropModelViewModel_ reset() {
onModelUnboundListener_epoxyGeneratedModel = null;
onModelVisibilityStateChangedListener_epoxyGeneratedModel = null;
onModelVisibilityChangedListener_epoxyGeneratedModel = null;
assignedAttributes_epoxyGeneratedModel.clear();
this.onClickListener_OnClickListener = (View.OnClickListener) null;
super.reset();
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package com.airbnb.epoxy.processor

import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_GENERATE_RESET
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_ENABLE_PARALLEL
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_LOG_TIMINGS
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_REQUIRE_HASHCODE
import com.airbnb.epoxy.processor.ConfigManager.Companion.PROCESSOR_OPTION_VALIDATE_MODEL_USAGE
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.Filer
import javax.annotation.processing.Messager
Expand Down Expand Up @@ -77,13 +87,16 @@ abstract class BaseProcessor : AbstractProcessor(), Asyncable {
abstract fun supportedAnnotations(): List<KClass<*>>

override fun getSupportedOptions(): Set<String> = setOf(
ConfigManager.PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS,
ConfigManager.PROCESSOR_OPTION_VALIDATE_MODEL_USAGE,
ConfigManager.PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS,
ConfigManager.PROCESSOR_OPTION_REQUIRE_HASHCODE,
ConfigManager.PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION,
ConfigManager.PROCESSOR_OPTION_LOG_TIMINGS,
ConfigManager.PROCESSOR_OPTION_ENABLE_PARALLEL
PROCESSOR_OPTION_IMPLICITLY_ADD_AUTO_MODELS,
PROCESSOR_OPTION_VALIDATE_MODEL_USAGE,
PROCESSOR_OPTION_REQUIRE_ABSTRACT_MODELS,
PROCESSOR_OPTION_REQUIRE_HASHCODE,
PROCESSOR_OPTION_DISABLE_KOTLIN_EXTENSION_GENERATION,
PROCESSOR_OPTION_LOG_TIMINGS,
PROCESSOR_OPTION_ENABLE_PARALLEL,
PROCESSOR_OPTION_DISABLE_GENERATE_RESET,
PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS,
PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS
)

override fun init(processingEnv: ProcessingEnvironment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class ConfigManager internal constructor(
private val globalRequireAbstractModels: Boolean
private val globalImplicitlyAddAutoModels: Boolean
private val disableKotlinExtensionGeneration: Boolean
private val disableGenerateReset: Boolean
private val disableGenerateGetters: Boolean
private val disableGenerateBuilderOverloads: Boolean
val logTimings: Boolean
val enableCoroutines: Boolean

Expand Down Expand Up @@ -71,6 +74,24 @@ class ConfigManager internal constructor(
PROCESSOR_OPTION_ENABLE_PARALLEL,
defaultValue = false
)

disableGenerateReset = getBooleanOption(
options,
PROCESSOR_OPTION_DISABLE_GENERATE_RESET,
defaultValue = false
)

disableGenerateGetters = getBooleanOption(
options,
PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS,
defaultValue = false
)

disableGenerateBuilderOverloads = getBooleanOption(
options,
PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS,
defaultValue = false
)
}

fun processPackageEpoxyConfig(roundEnv: RoundEnvironment): List<Exception> {
Expand Down Expand Up @@ -185,6 +206,11 @@ class ConfigManager internal constructor(
*/
fun shouldValidateModelUsage(): Boolean = validateModelUsage

fun getModelViewConfig(modelViewInfo: ModelViewInfo?): PackageModelViewSettings? {
if (modelViewInfo == null) return null
return getModelViewConfig(modelViewInfo.viewElement)
}

fun getModelViewConfig(viewElement: Element): PackageModelViewSettings? {
val packageName = elementUtils.getPackageOf(viewElement).qualifiedName.toString()
return getObjectFromPackageMap(
Expand All @@ -207,6 +233,21 @@ class ConfigManager internal constructor(
?: GeneratedModelInfo.GENERATED_MODEL_SUFFIX
}

fun disableGenerateBuilderOverloads(modelInfo: GeneratedModelInfo): Boolean {
return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateBuilderOverloads
?: disableGenerateBuilderOverloads
}

fun disableGenerateReset(modelInfo: GeneratedModelInfo): Boolean {
return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateReset
?: disableGenerateReset
}

fun disableGenerateGetters(modelInfo: GeneratedModelInfo): Boolean {
return getModelViewConfig(modelInfo as? ModelViewInfo)?.disableGenerateGetters
?: disableGenerateGetters
}

private fun getConfigurationForElement(element: Element): PackageConfigSettings {
return getConfigurationForPackage(elementUtils.getPackageOf(element))
}
Expand All @@ -225,6 +266,10 @@ class ConfigManager internal constructor(
}

companion object {
const val PROCESSOR_OPTION_DISABLE_GENERATE_RESET = "epoxyDisableGenerateReset"
const val PROCESSOR_OPTION_DISABLE_GENERATE_GETTERS = "epoxyDisableGenerateGetters"
const val PROCESSOR_OPTION_DISABLE_GENERATE_BUILDER_OVERLOADS =
"epoxyDisableGenerateOverloads"
const val PROCESSOR_OPTION_LOG_TIMINGS = "logEpoxyTimings"
const val PROCESSOR_OPTION_ENABLE_PARALLEL = "enableParallelEpoxyProcessing"
const val PROCESSOR_OPTION_VALIDATE_MODEL_USAGE = "validateEpoxyModelUsage"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ abstract class GeneratedModelInfo(val memoizer: Memoizer) {
return attributeToGroup[attribute]?.attributes?.let { it.size > 1 } == true
}

fun attributeGroup(attribute: AttributeInfo): AttributeGroup? {
return attributeToGroup[attribute]
}

class AttributeGroup internal constructor(
groupName: String?,
attributes: List<AttributeInfo>,
Expand Down
Loading

0 comments on commit 4a2c055

Please sign in to comment.