-
Notifications
You must be signed in to change notification settings - Fork 730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate model factory methods #450
Conversation
@@ -998,7 +1089,7 @@ internal class GeneratedModelWriter( | |||
if (attr is ViewAttributeInfo && attr.generateStringOverloads) { | |||
methods.addAll(StringOverloadWriter(modelInfo, attr, configManager).buildMethods()) | |||
} else { | |||
if (attr.isViewClickListener) { | |||
if (attr.isViewClickListener || attr.isViewLongClickListener) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this is a change (though not a functional one, I modified isViewClickListener
so I could use it elsewhere).
@@ -1295,6 +1412,106 @@ internal class GeneratedModelWriter( | |||
return method | |||
} | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here's the main addition besides tests.
|
||
javaCompileOptions { | ||
annotationProcessorOptions { | ||
includeCompileClasspath false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it so Gradle doesn't complain that there are undeclared annotation processors in the classpath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave a code comment about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems a bit redundant, the config itself is pretty explicit: don't include annotation processors that are in the compile classpath, which this module does because it's testing them with the google testing compile lib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well you still left a github comment explaining it, so it isn't too explicit ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only because it doesn't seem directly related to this PR. 😛
6e0e8fb
to
f101814
Compare
f101814
to
d4ee671
Compare
double getDouble(@NonNull String propertyName); | ||
|
||
@NonNull | ||
Drawable getDrawable(@NonNull String propertyName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could support getDrawableRes
by looking for @DrawableRes annotation
import java.util.List; | ||
|
||
public interface ModelProperties { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dedicated getId()
method?
|
||
import java.util.List; | ||
|
||
public interface ModelProperties { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can use kotlin for this module
|
||
internal object ProcessorTestUtils { | ||
@JvmOverloads | ||
@JvmStatic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need the jvm helpers
} | ||
|
||
val supportedAttributeInfo = modelInfo.attributeInfo.filter { attributeInfo -> | ||
listOf( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be easier to read to have this list declared outside the loop
attributeInfo.isDrawable -> "getDrawable" | ||
attributeInfo.isInt -> "getInt" | ||
attributeInfo.isViewClickListener -> "getOnClickListener" | ||
else -> throw IllegalStateException() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put a message in the exception
} | ||
|
||
// Groups aren't supported because we wouldn't know which type to choose from | ||
if (modelInfo.attributeGroups.any { it.attributes.size > 1 }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check this before supported attributes?
} | ||
|
||
// If none of the properties are of a supported type the method isn't generated | ||
if (supportedAttributeInfo.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be an error if any attributes are not supported?
|
||
javaCompileOptions { | ||
annotationProcessorOptions { | ||
includeCompileClasspath false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave a code comment about it?
…ttributes of a supported type
@elihart addressed all the feedback. 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! ship it 🚀
|
||
interface ModelProperties { | ||
|
||
fun getId(): String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why fun over val?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With everything else being a function it seemed inconsistent/out of place. 🤷♂️
|
||
javaCompileOptions { | ||
annotationProcessorOptions { | ||
includeCompileClasspath false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well you still left a github comment explaining it, so it isn't too explicit ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ngsilverman great, updates look nice. thanks!
boolean isEpoxyModelList() { | ||
return Utils.isType( | ||
getTypeMirror(), | ||
"java.util.List<? extends com.airbnb.epoxy.EpoxyModel<?>>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about kotlin support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elihart after doing some testing I just realized that we don't need to check for Kotlin types at all (for lists, strings or charsequences alike). Guess they get converted to Java types for interop.
} | ||
|
||
boolean isStringList() { | ||
return Utils.isType(getTypeMirror(), "java.util.List<java.lang.String>") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a good way to DRY up the two list checks is to have a isList(type)
method that checks for java/kotlin lists and also checks the generic type as a parameter
boolean isEpoxyModelList() { | ||
return Utils.isType( | ||
getTypeMirror(), | ||
"java.util.List<? extends com.airbnb.epoxy.EpoxyModel<?>>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be nice to use a ClassName constant or something, not sure if that is possible with the wildcard
|| isStringType(type); | ||
} | ||
|
||
static boolean isStringAttributeDataType(TypeMirror type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to have a generic isType(TypeMirror , ClassName)
method?
) { | ||
// The epoxy-modelfactory module must be present to enable this functionality | ||
val hasModelFactoryDependency = | ||
getTypeMirror(EPOXY_MODEL_PROPERTIES.reflectionName(), elements) != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opportunity for an elements.isTypeLoaded(ClassName)
extension
|
||
// Models that don't have an empty constructor are not supported because there would be no | ||
// clear way to create new instances | ||
val hasEmptyConstructor = modelInfo.constructors.isEmpty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this be a method on the ModelInfo class?
@elihart Added a Kotlin view test and followed your suggestions. Let me know if this is good to go. Do you want me to handle the release? |
@ngsilverman yeah, seems good to go. if you can do the release that'd be great |
epoxy-modelfactory
ModelProperties
interfaceModelProperties
to set stylesepoxy-processortest
to reuseProcessorTestUtils
but that caused mysterious Lint issues so I copied a single method from it over instead.from(ModelProperties properties)
method is generated.TODO
(I rebased and reformatted
GeneratedModelWriter
but nothing changed. Maybe it hadn't been properly formatted in the first place?)