Skip to content

Commit

Permalink
#398 Custom generated view model suffix (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
geralt-encore authored and elihart committed Feb 15, 2018
1 parent ab8ba02 commit 5dcdb93
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@
* other layout instead of the default.
*/
boolean useLayoutOverloads() default false;

/**
* Suffix, which will be appended to generated model's names. "Model_" is a default value.
*/
String generatedModelSuffix() default "Model_";
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,15 @@ boolean includeAlternateLayoutsForViews(TypeElement viewElement) {
return modelViewConfig.getIncludeAlternateLayouts();
}

String generatedModelSuffix(TypeElement viewElement) {
PackageModelViewSettings modelViewConfig = getModelViewConfig(viewElement);
if (modelViewConfig == null) {
return GeneratedModelInfo.GENERATED_MODEL_SUFFIX;
}

return modelViewConfig.getGeneratedModelSuffix();
}

private PackageConfigSettings getConfigurationForElement(Element element) {
return getConfigurationForPackage(elementUtils.getPackageOf(element));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal class ModelViewInfo(
val saveViewState: Boolean
private val viewAnnotation: ModelView = viewElement.getAnnotation(ModelView::class.java)
val fullSpanSize: Boolean
val generatedModelSuffix: String

/** All interfaces the view implements that have at least one prop set by the interface. */
val viewInterfaces: List<TypeElement>
Expand All @@ -39,6 +40,7 @@ internal class ModelViewInfo(
this.superClassName = ParameterizedTypeName
.get(ClassName.get(superClassElement), TypeName.get(viewElement.asType()))

generatedModelSuffix = configManager.generatedModelSuffix(viewElement)
generatedClassName = buildGeneratedModelName(viewElement, elements)
// We don't have any type parameters on our generated model
this.parametrizedClassName = generatedClassName
Expand Down Expand Up @@ -156,7 +158,7 @@ internal class ModelViewInfo(
val packageName = elementUtils.getPackageOf(viewElement).qualifiedName.toString()

var className = viewElement.simpleName.toString()
className += GeneratedModelInfo.GENERATED_MODEL_SUFFIX
className += generatedModelSuffix

return ClassName.get(packageName, className)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class PackageModelViewSettings(
val layoutName: String = annotation.defaultLayoutPattern
val defaultBaseModel: TypeMirror? = getDefaultBaseModel(annotation)
val includeAlternateLayouts: Boolean = annotation.useLayoutOverloads
val generatedModelSuffix: String = annotation.generatedModelSuffix

private fun getDefaultBaseModel(annotation: PackageModelViewConfig): TypeMirror? {
var defaultBaseModel: TypeMirror? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.airbnb.epoxy

import com.airbnb.epoxy.ProcessorTestUtils.*
import com.google.common.collect.ImmutableList
import com.google.common.truth.Truth.*
import com.google.testing.compile.*
import com.google.testing.compile.JavaSourcesSubjectFactory.*
import org.junit.*
import java.util.Arrays.*
import com.airbnb.epoxy.ProcessorTestUtils.assertGeneration
import com.airbnb.epoxy.ProcessorTestUtils.assertGenerationError
import com.google.common.truth.Truth.assert_
import com.google.testing.compile.JavaFileObjects
import com.google.testing.compile.JavaSourcesSubjectFactory.javaSources
import org.junit.Test
import java.util.Arrays.asList

class ViewProcessorTest {

Expand Down Expand Up @@ -620,6 +620,52 @@ class ViewProcessorTest {
.generatesSources(generatedModel)
}

@Test
fun generatedModelSuffix() {
val model = JavaFileObjects
.forSourceLines("com.airbnb.epoxy.GeneratedModelSuffixView",
"package com.airbnb.epoxy;\n"
+ "\n"
+ "import android.content.Context;\n"
+ "import android.view.View;\n"
+ "\n"
+ "@ModelView\n"
+ "public class GeneratedModelSuffixView extends View {\n"
+ "\n"
+ " public GeneratedModelSuffixView(Context context) {\n"
+ " super(context);\n"
+ " }\n"
+ "\n"
+ "}")

val R = JavaFileObjects.forSourceString("com.airbnb.epoxy.R", ""
+ "package com.airbnb.epoxy;\n"
+ "public final class R {\n"
+ " public static final class layout {\n"
+ " public static final int generated_model_suffix_view = 0x7f040008;\n"
+ " }\n"
+ "}"
)

val configClass = JavaFileObjects
.forSourceLines("com.airbnb.epoxy.package-info",
"@PackageModelViewConfig(rClass = R"
+ ".class, generatedModelSuffix = \"Suffix_\")\n"
+ "package com.airbnb.epoxy;\n"
+ "\n"
+ "import com.airbnb.epoxy.PackageModelViewConfig;\n"
+ "import com.airbnb.epoxy.R;\n")

val generatedModel = JavaFileObjects.forResource("GeneratedModelSuffixViewSuffix_.java")

assert_().about(javaSources())
.that(asList(model, configClass, R))
.processedWith(EpoxyProcessor())
.compilesWithoutError()
.and()
.generatesSources(generatedModel)
}

@Test
fun afterBindProps() {
val model = JavaFileObjects
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package com.airbnb.epoxy;

import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.CharSequence;
import java.lang.Number;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.util.BitSet;

/**
* Generated file. Do not modify! */
public class GeneratedModelSuffixViewSuffix_ extends EpoxyModel<GeneratedModelSuffixView> implements GeneratedModel<GeneratedModelSuffixView>, GeneratedModelSuffixViewSuffixBuilder {
private final BitSet assignedAttributes_epoxyGeneratedModel = new BitSet(0);

private OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelBoundListener_epoxyGeneratedModel;

private OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> onModelUnboundListener_epoxyGeneratedModel;

@Override
public void addTo(EpoxyController controller) {
super.addTo(controller);
addWithDebugValidation(controller);
}

@Override
public void handlePreBind(final EpoxyViewHolder holder, final GeneratedModelSuffixView object,
int position) {
validateStateHasNotChangedSinceAdded("The model was changed between being added to the controller and being bound.", position);
}

@Override
public void bind(final GeneratedModelSuffixView object) {
super.bind(object);
}

@Override
public void bind(final GeneratedModelSuffixView object, EpoxyModel previousModel) {
if (!(previousModel instanceof GeneratedModelSuffixViewSuffix_)) {
bind(object);
return;
}
GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) previousModel;
super.bind(object);
}

@Override
public void handlePostBind(final GeneratedModelSuffixView object, int position) {
if (onModelBoundListener_epoxyGeneratedModel != null) {
onModelBoundListener_epoxyGeneratedModel.onModelBound(this, object, position);
}
validateStateHasNotChangedSinceAdded("The model was changed during the bind call.", position);
}

/**
* Register a listener that will be called when this model is bound to a view.
* <p>
* The listener will contribute to this model's hashCode state per the {@link
* com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.
* <p>
* You may clear the listener by setting a null value, or by calling {@link #reset()} */
public GeneratedModelSuffixViewSuffix_ onBind(OnModelBoundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {
onMutation();
this.onModelBoundListener_epoxyGeneratedModel = listener;
return this;
}

@Override
public void unbind(GeneratedModelSuffixView object) {
super.unbind(object);
if (onModelUnboundListener_epoxyGeneratedModel != null) {
onModelUnboundListener_epoxyGeneratedModel.onModelUnbound(this, object);
}
}

/**
* Register a listener that will be called when this model is unbound from a view.
* <p>
* The listener will contribute to this model's hashCode state per the {@link
* com.airbnb.epoxy.EpoxyAttribute.Option#DoNotHash} rules.
* <p>
* You may clear the listener by setting a null value, or by calling {@link #reset()} */
public GeneratedModelSuffixViewSuffix_ onUnbind(OnModelUnboundListener<GeneratedModelSuffixViewSuffix_, GeneratedModelSuffixView> listener) {
onMutation();
this.onModelUnboundListener_epoxyGeneratedModel = listener;
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(long id) {
super.id(id);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(@NonNull Number... arg0) {
super.id(arg0);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(long id1, long id2) {
super.id(id1, id2);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(@NonNull CharSequence arg0) {
super.id(arg0);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(@NonNull CharSequence arg0,
@NonNull CharSequence... arg1) {
super.id(arg0, arg1);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ id(@NonNull CharSequence arg0, long arg1) {
super.id(arg0, arg1);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ layout(@LayoutRes int arg0) {
super.layout(arg0);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ spanSizeOverride(@Nullable EpoxyModel.SpanSizeOverrideCallback arg0) {
super.spanSizeOverride(arg0);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ show() {
super.show();
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ show(boolean show) {
super.show(show);
return this;
}

@Override
public GeneratedModelSuffixViewSuffix_ hide() {
super.hide();
return this;
}

@Override
@LayoutRes
protected int getDefaultLayout() {
return R.layout.generated_model_suffix_view;
}

@Override
public GeneratedModelSuffixViewSuffix_ reset() {
onModelBoundListener_epoxyGeneratedModel = null;
onModelUnboundListener_epoxyGeneratedModel = null;
assignedAttributes_epoxyGeneratedModel.clear();
super.reset();
return this;
}

@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof GeneratedModelSuffixViewSuffix_)) {
return false;
}
if (!super.equals(o)) {
return false;
}
GeneratedModelSuffixViewSuffix_ that = (GeneratedModelSuffixViewSuffix_) o;
if (((onModelBoundListener_epoxyGeneratedModel == null) != (that.onModelBoundListener_epoxyGeneratedModel == null))) {
return false;
}
if (((onModelUnboundListener_epoxyGeneratedModel == null) != (that.onModelUnboundListener_epoxyGeneratedModel == null))) {
return false;
}
return true;
}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (onModelBoundListener_epoxyGeneratedModel != null ? 1 : 0);
result = 31 * result + (onModelUnboundListener_epoxyGeneratedModel != null ? 1 : 0);
return result;
}

@Override
public String toString() {
return "GeneratedModelSuffixViewSuffix_{" +
"}" + super.toString();
}

@Override
public int getSpanSize(int totalSpanCount, int position, int itemCount) {
return totalSpanCount;
}
}

0 comments on commit 5dcdb93

Please sign in to comment.