use of javax.lang.model.element.TypeElement in project epoxy by airbnb.
the class HashCodeValidator method hasHashCodeInClassHierarchy.
private boolean hasHashCodeInClassHierarchy(TypeElement clazz) {
ExecutableElement methodOnClass = getMethodOnClass(clazz, HASH_CODE_METHOD, typeUtils);
if (methodOnClass == null) {
return false;
}
Element implementingClass = methodOnClass.getEnclosingElement();
if (implementingClass.getSimpleName().toString().equals("Object")) {
// Don't count default implementation on Object class
return false;
}
// correctly :P)
return true;
}
use of javax.lang.model.element.TypeElement in project epoxy by airbnb.
the class HashCodeValidator method validateImplementsHashCode.
private void validateImplementsHashCode(TypeMirror mirror) throws EpoxyProcessorException {
if (TypeName.get(mirror).isPrimitive()) {
return;
}
if (mirror.getKind() == TypeKind.ARRAY) {
validateArrayType((ArrayType) mirror);
return;
}
if (!(mirror instanceof DeclaredType)) {
return;
}
DeclaredType declaredType = (DeclaredType) mirror;
Element element = typeUtils.asElement(mirror);
TypeElement clazz = (TypeElement) element;
if (isIterableType(clazz)) {
validateIterableType(declaredType);
return;
}
if (isAutoValueType(element)) {
return;
}
if (isWhiteListedType(element)) {
return;
}
if (!hasHashCodeInClassHierarchy(clazz)) {
throwError("Attribute does not implement hashCode");
}
}
use of javax.lang.model.element.TypeElement in project epoxy by airbnb.
the class ProcessorUtils method isSubtypeOfType.
static boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) {
if (otherType.equals(typeMirror.toString())) {
return true;
}
if (typeMirror.getKind() != TypeKind.DECLARED) {
return false;
}
DeclaredType declaredType = (DeclaredType) typeMirror;
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (typeArguments.size() > 0) {
StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());
typeString.append('<');
for (int i = 0; i < typeArguments.size(); i++) {
if (i > 0) {
typeString.append(',');
}
typeString.append('?');
}
typeString.append('>');
if (typeString.toString().equals(otherType)) {
return true;
}
}
Element element = declaredType.asElement();
if (!(element instanceof TypeElement)) {
return false;
}
TypeElement typeElement = (TypeElement) element;
TypeMirror superType = typeElement.getSuperclass();
if (isSubtypeOfType(superType, otherType)) {
return true;
}
for (TypeMirror interfaceType : typeElement.getInterfaces()) {
if (isSubtypeOfType(interfaceType, otherType)) {
return true;
}
}
return false;
}
use of javax.lang.model.element.TypeElement in project epoxy by airbnb.
the class EpoxyProcessor method findClassAnnotationWithLayout.
/**
* Looks for {@link EpoxyModelClass} annotation in the original class and his parents.
*/
private EpoxyModelClass findClassAnnotationWithLayout(TypeElement classElement) {
if (!isEpoxyModel(classElement)) {
return null;
}
EpoxyModelClass annotation = classElement.getAnnotation(EpoxyModelClass.class);
if (annotation == null) {
return null;
}
try {
int layoutRes = annotation.layout();
if (layoutRes != 0) {
return annotation;
}
} catch (AnnotationTypeMismatchException e) {
logError("Invalid layout value in %s annotation. (class: %s). %s: %s", EpoxyModelClass.class, classElement.getSimpleName(), e.getClass().getSimpleName(), e.getMessage());
return null;
}
TypeElement superclassElement = (TypeElement) typeUtils.asElement(classElement.getSuperclass());
EpoxyModelClass annotationOnSuperClass = findClassAnnotationWithLayout(superclassElement);
// Return the last annotation value we have so the proper error can be thrown if needed
return annotationOnSuperClass != null ? annotationOnSuperClass : annotation;
}
use of javax.lang.model.element.TypeElement in project epoxy by airbnb.
the class EpoxyProcessor method validateAccessibleViaGeneratedCode.
private void validateAccessibleViaGeneratedCode(Element attribute) {
TypeElement enclosingElement = (TypeElement) attribute.getEnclosingElement();
// Verify method modifiers.
Set<Modifier> modifiers = attribute.getModifiers();
if (modifiers.contains(PRIVATE) || modifiers.contains(STATIC)) {
logError("%s annotations must not be on private or static fields. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
}
// Nested classes must be static
if (enclosingElement.getNestingKind().isNested()) {
if (!enclosingElement.getModifiers().contains(STATIC)) {
logError("Nested classes with %s annotations must be static. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
}
}
// Verify containing type.
if (enclosingElement.getKind() != CLASS) {
logError("%s annotations may only be contained in classes. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
}
// Verify containing class visibility is not private.
if (enclosingElement.getModifiers().contains(PRIVATE)) {
logError("%s annotations may not be contained in private classes. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
}
}
Aggregations