From ab8ce375e254fd3507479672410d52cec057133e Mon Sep 17 00:00:00 2001 From: Eli Hart Date: Tue, 9 Nov 2021 16:14:03 -0800 Subject: [PATCH] Fix crash from empty list (#1249) --- .../com/airbnb/epoxy/processor/Memoizer.kt | 3 +- .../epoxy/processor/ModelViewProcessor.kt | 8 ++++++ .../SourceView.kt | 5 ++++ .../SourceViewModelBuilder.java | 2 ++ .../SourceViewModel_.java | 28 +++++++++++++++++++ .../ksp/SourceViewModelBuilder.java | 2 ++ .../ksp/SourceViewModel_.java | 28 +++++++++++++++++++ gradle.properties | 2 +- 8 files changed, 75 insertions(+), 3 deletions(-) diff --git a/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Memoizer.kt b/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Memoizer.kt index d0b72a863b..af533e9889 100644 --- a/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Memoizer.kt +++ b/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/Memoizer.kt @@ -331,13 +331,12 @@ class Memoizer( viewModelAnnotations.forEach { annotation -> superViewElement.getElementsAnnotatedWith(annotation).forEach { element -> - val isPackagePrivate by lazy { Utils.isFieldPackagePrivate(element) } annotatedElements .getOrPut(annotation) { mutableListOf() } .add( ViewElement( element = element, - isPackagePrivate = isPackagePrivate, + isPackagePrivate = Utils.isFieldPackagePrivate(element), attributeInfo = lazy { ViewAttributeInfo( viewElement = superViewElement, diff --git a/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewProcessor.kt b/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewProcessor.kt index f7302d57c7..c99145f343 100644 --- a/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewProcessor.kt +++ b/epoxy-processor/src/main/java/com/airbnb/epoxy/processor/ModelViewProcessor.kt @@ -573,6 +573,14 @@ class ModelViewProcessor @JvmOverloads constructor( // We don't want the attribute from the super class replacing an attribute in the // subclass if the subclass overrides it, since the subclass definition could include // different annotation parameter settings, or we could end up with duplicates + + // If an annotated prop method has a default value it will also have @JvmOverloads + // so java source in KAPT sees both a zero param and and 1 param method. We just + // ignore the empty param version. + if (it.element is XMethodElement && it.element.parameters.size != 1) { + return@forEachElementWithAnnotation + } + view.addAttributeIfNotExists(it.attributeInfo.value) } diff --git a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt index d6c54ee4c1..db08d98805 100644 --- a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt +++ b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceView.kt @@ -44,5 +44,10 @@ open class BaseView(context: Context) : View(context) { @ModelProp fun baseViewProp(prop: Int) { } + + @JvmOverloads + @ModelProp + fun baseViewPropWithDefaultParamValue(prop: Int = 0) { + } } diff --git a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java index a1be83b0c4..fd267b8c23 100644 --- a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java +++ b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModelBuilder.java @@ -22,6 +22,8 @@ SourceViewModelBuilder onVisibilityChanged( SourceViewModelBuilder baseViewProp(int baseViewProp); + SourceViewModelBuilder baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue); + SourceViewModelBuilder showDividerWithSetter(Boolean showDividerWithSetter); SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider); diff --git a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java index b216734c97..0e43ac7553 100644 --- a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java +++ b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/SourceViewModel_.java @@ -28,6 +28,8 @@ public class SourceViewModel_ extends AirEpoxyModel implements Gener private int baseViewProp_Int = 0; + private int baseViewPropWithDefaultParamValue_Int = 0; + public SourceViewModel_() { super(); } @@ -60,6 +62,7 @@ public void handlePreBind(final EpoxyViewHolder holder, final SourceView object, public void bind(final SourceView object) { super.bind(object); object.setSectionId(sectionId_String); + object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int); object.baseViewProp(baseViewProp_Int); } @@ -76,6 +79,10 @@ public void bind(final SourceView object, EpoxyModel previousModel) { object.setSectionId(sectionId_String); } + if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) { + object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int); + } + if ((baseViewProp_Int != that.baseViewProp_Int)) { object.baseViewProp(baseViewProp_Int); } @@ -199,6 +206,21 @@ public int baseViewProp() { return baseViewProp_Int; } + /** + * Optional: Default value is 0 + * + * @see BaseView#baseViewPropWithDefaultParamValue(int) + */ + public SourceViewModel_ baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue) { + onMutation(); + this.baseViewPropWithDefaultParamValue_Int = baseViewPropWithDefaultParamValue; + return this; + } + + public int baseViewPropWithDefaultParamValue() { + return baseViewPropWithDefaultParamValue_Int; + } + public SourceViewModel_ showDividerWithSetter(Boolean showDividerWithSetter) { onMutation(); super.setShowDividerWithSetter(showDividerWithSetter); @@ -302,6 +324,7 @@ public SourceViewModel_ reset() { onModelVisibilityChangedListener_epoxyGeneratedModel = null; this.sectionId_String = (String) null; this.baseViewProp_Int = 0; + this.baseViewPropWithDefaultParamValue_Int = 0; super.setShowDivider(null); super.setShowDividerWithSetter(null); super.reset(); @@ -338,6 +361,9 @@ public boolean equals(Object o) { if ((baseViewProp_Int != that.baseViewProp_Int)) { return false; } + if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) { + return false; + } if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) { return false; } @@ -356,6 +382,7 @@ public int hashCode() { _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0); _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0); _result = 31 * _result + baseViewProp_Int; + _result = 31 * _result + baseViewPropWithDefaultParamValue_Int; _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0); _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0); return _result; @@ -366,6 +393,7 @@ public String toString() { return "SourceViewModel_{" + "sectionId_String=" + sectionId_String + ", baseViewProp_Int=" + baseViewProp_Int + + ", baseViewPropWithDefaultParamValue_Int=" + baseViewPropWithDefaultParamValue_Int + ", showDivider=" + getShowDivider() + ", showDividerWithSetter=" + getShowDividerWithSetter() + "}" + super.toString(); diff --git a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModelBuilder.java b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModelBuilder.java index e28923346f..f85dbc7961 100644 --- a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModelBuilder.java +++ b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModelBuilder.java @@ -22,6 +22,8 @@ SourceViewModelBuilder onVisibilityChanged( SourceViewModelBuilder baseViewProp(int baseViewProp); + SourceViewModelBuilder baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue); + SourceViewModelBuilder showDividerWithSetter(@Nullable Boolean showDividerWithSetter); SourceViewModelBuilder showDividerWithOverriddenMethod(boolean showDivider); diff --git a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModel_.java b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModel_.java index 2e58e84066..ade9c2a7cd 100644 --- a/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModel_.java +++ b/epoxy-processortest/src/test/resources/ViewProcessorTest/inheritingAttributesWorksCorrectly/ksp/SourceViewModel_.java @@ -28,6 +28,8 @@ public class SourceViewModel_ extends AirEpoxyModel implements Gener private int baseViewProp_Int = 0; + private int baseViewPropWithDefaultParamValue_Int = 0; + public SourceViewModel_() { super(); } @@ -60,6 +62,7 @@ public void handlePreBind(final EpoxyViewHolder holder, final SourceView object, public void bind(final SourceView object) { super.bind(object); object.setSectionId(sectionId_String); + object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int); object.baseViewProp(baseViewProp_Int); } @@ -76,6 +79,10 @@ public void bind(final SourceView object, EpoxyModel previousModel) { object.setSectionId(sectionId_String); } + if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) { + object.baseViewPropWithDefaultParamValue(baseViewPropWithDefaultParamValue_Int); + } + if ((baseViewProp_Int != that.baseViewProp_Int)) { object.baseViewProp(baseViewProp_Int); } @@ -199,6 +206,21 @@ public int baseViewProp() { return baseViewProp_Int; } + /** + * Optional: Default value is 0 + * + * @see BaseView#baseViewPropWithDefaultParamValue(int) + */ + public SourceViewModel_ baseViewPropWithDefaultParamValue(int baseViewPropWithDefaultParamValue) { + onMutation(); + this.baseViewPropWithDefaultParamValue_Int = baseViewPropWithDefaultParamValue; + return this; + } + + public int baseViewPropWithDefaultParamValue() { + return baseViewPropWithDefaultParamValue_Int; + } + public SourceViewModel_ showDividerWithSetter(@Nullable Boolean showDividerWithSetter) { onMutation(); super.setShowDividerWithSetter(showDividerWithSetter); @@ -301,6 +323,7 @@ public SourceViewModel_ reset() { onModelVisibilityChangedListener_epoxyGeneratedModel = null; this.sectionId_String = (String) null; this.baseViewProp_Int = 0; + this.baseViewPropWithDefaultParamValue_Int = 0; super.setShowDivider(null); super.setShowDividerWithSetter(null); super.reset(); @@ -337,6 +360,9 @@ public boolean equals(Object o) { if ((baseViewProp_Int != that.baseViewProp_Int)) { return false; } + if ((baseViewPropWithDefaultParamValue_Int != that.baseViewPropWithDefaultParamValue_Int)) { + return false; + } if ((getShowDivider() != null ? !getShowDivider().equals(that.getShowDivider()) : that.getShowDivider() != null)) { return false; } @@ -355,6 +381,7 @@ public int hashCode() { _result = 31 * _result + (onModelVisibilityChangedListener_epoxyGeneratedModel != null ? 1 : 0); _result = 31 * _result + (sectionId_String != null ? sectionId_String.hashCode() : 0); _result = 31 * _result + baseViewProp_Int; + _result = 31 * _result + baseViewPropWithDefaultParamValue_Int; _result = 31 * _result + (getShowDivider() != null ? getShowDivider().hashCode() : 0); _result = 31 * _result + (getShowDividerWithSetter() != null ? getShowDividerWithSetter().hashCode() : 0); return _result; @@ -365,6 +392,7 @@ public String toString() { return "SourceViewModel_{" + "sectionId_String=" + sectionId_String + ", baseViewProp_Int=" + baseViewProp_Int + + ", baseViewPropWithDefaultParamValue_Int=" + baseViewPropWithDefaultParamValue_Int + ", showDivider=" + getShowDivider() + ", showDividerWithSetter=" + getShowDividerWithSetter() + "}" + super.toString(); diff --git a/gradle.properties b/gradle.properties index 0d2c2ffff1..1ac9f328ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=5.0.0-beta02 +VERSION_NAME=5.0.0-beta03 GROUP=com.airbnb.android POM_DESCRIPTION=Epoxy is a system for composing complex screens with a ReyclerView in Android. POM_URL=https://github.com/airbnb/epoxy